@steadybrew/postgresjs 4.3.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -2
- package/cf/src/connection.js +59 -19
- package/cf/src/errors.js +8 -0
- package/cf/src/index.js +61 -34
- package/cf/src/subscribe.js +127 -47
- package/cjs/src/connection.js +59 -19
- package/cjs/src/errors.js +8 -0
- package/cjs/src/index.js +61 -34
- package/cjs/src/subscribe.js +127 -47
- package/package.json +1 -1
- package/src/connection.js +59 -19
- package/src/errors.js +8 -0
- package/src/index.js +61 -34
- package/src/subscribe.js +127 -47
- package/types/index.d.ts +9 -9
package/cf/src/subscribe.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer'
|
|
2
|
+
import { callback } from './errors.js'
|
|
3
|
+
import { defaultBackoff, backoffSeconds } from './connection.js'
|
|
4
|
+
|
|
2
5
|
const noop = () => { /* noop */ }
|
|
6
|
+
, commands = { 68: 'delete', 73: 'insert', 85: 'update' }
|
|
7
|
+
, statusInterval = 1000
|
|
3
8
|
|
|
4
9
|
export default function Subscribe(postgres, options) {
|
|
5
10
|
const subscribers = new Map()
|
|
@@ -8,6 +13,9 @@ export default function Subscribe(postgres, options) {
|
|
|
8
13
|
|
|
9
14
|
let connection
|
|
10
15
|
, stream
|
|
16
|
+
, timer
|
|
17
|
+
, inflight = false
|
|
18
|
+
, retries = 0
|
|
11
19
|
, ended = false
|
|
12
20
|
|
|
13
21
|
const sql = subscribe.sql = postgres({
|
|
@@ -22,13 +30,12 @@ export default function Subscribe(postgres, options) {
|
|
|
22
30
|
...options.connection,
|
|
23
31
|
replication: 'database'
|
|
24
32
|
},
|
|
25
|
-
onclose:
|
|
33
|
+
onclose: function() {
|
|
26
34
|
if (ended)
|
|
27
35
|
return
|
|
28
36
|
stream = null
|
|
29
37
|
state.pid = state.secret = undefined
|
|
30
|
-
|
|
31
|
-
subscribers.forEach(event => event.forEach(({ onsubscribe }) => onsubscribe()))
|
|
38
|
+
inflight || timer || !connection || connect().catch(noop)
|
|
32
39
|
},
|
|
33
40
|
no_subscribe: true
|
|
34
41
|
})
|
|
@@ -38,6 +45,9 @@ export default function Subscribe(postgres, options) {
|
|
|
38
45
|
|
|
39
46
|
sql.end = async() => {
|
|
40
47
|
ended = true
|
|
48
|
+
clearTimeout(timer)
|
|
49
|
+
timer = null
|
|
50
|
+
connection && await connection.catch(noop)
|
|
41
51
|
stream && (await new Promise(r => (stream.once('close', r), stream.end())))
|
|
42
52
|
return end()
|
|
43
53
|
}
|
|
@@ -49,34 +59,74 @@ export default function Subscribe(postgres, options) {
|
|
|
49
59
|
|
|
50
60
|
return subscribe
|
|
51
61
|
|
|
52
|
-
async function subscribe(event, fn, onsubscribe = noop, onerror
|
|
62
|
+
async function subscribe(event, fn, onsubscribe = noop, onerror) {
|
|
53
63
|
event = parseEvent(event)
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
connection = init(sql, slot, options.publications)
|
|
65
|
+
const subscriber = { fn, onsubscribe, onerror }
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
return (connection || connect()).then(() => {
|
|
68
|
+
const fns = subscribers.has(event)
|
|
69
|
+
? subscribers.get(event).add(subscriber)
|
|
70
|
+
: subscribers.set(event, new Set([subscriber])).get(event)
|
|
62
71
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
const unsubscribe = () => {
|
|
73
|
+
fns.delete(subscriber)
|
|
74
|
+
fns.size === 0 && subscribers.delete(event)
|
|
75
|
+
subscribers.size === 0 && (clearTimeout(timer), timer = null)
|
|
76
|
+
}
|
|
67
77
|
|
|
68
|
-
|
|
69
|
-
connected(x)
|
|
70
|
-
onsubscribe()
|
|
71
|
-
stream && stream.on('error', onerror)
|
|
78
|
+
callback(onsubscribe)
|
|
72
79
|
return { unsubscribe, state, sql }
|
|
73
80
|
})
|
|
74
81
|
}
|
|
75
82
|
|
|
76
|
-
function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
function connect() {
|
|
84
|
+
clearTimeout(timer)
|
|
85
|
+
timer = null
|
|
86
|
+
inflight = true
|
|
87
|
+
const resume = subscribers.size > 0
|
|
88
|
+
const current = connection = init(sql, slot, options.publications).then(x => {
|
|
89
|
+
stream = x.stream
|
|
90
|
+
state.pid = x.state.pid
|
|
91
|
+
state.secret = x.state.secret
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
current.then(
|
|
95
|
+
() => {
|
|
96
|
+
inflight = false
|
|
97
|
+
retries = 0
|
|
98
|
+
resume && !ended && subscribers.forEach(event => event.forEach(({ onsubscribe }) => callback(onsubscribe)))
|
|
99
|
+
},
|
|
100
|
+
error => {
|
|
101
|
+
inflight = false
|
|
102
|
+
connection === current && (connection = null)
|
|
103
|
+
if (ended || subscribers.size === 0)
|
|
104
|
+
return
|
|
105
|
+
reportConnection(error)
|
|
106
|
+
timer = setTimeout(() => connect().catch(noop), retryDelay(retries++))
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
return current
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function retryDelay(n) {
|
|
114
|
+
let seconds = backoffSeconds(sql.options.backoff, n)
|
|
115
|
+
seconds = Number.isFinite(seconds) ? seconds : defaultBackoff(n)
|
|
116
|
+
return Math.min(Math.max(seconds * 1000, 100), 2 ** 31 - 1)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function reportConnection(error) {
|
|
120
|
+
console.error('Unexpected error during logical streaming - reconnecting', error) // eslint-disable-line
|
|
121
|
+
subscribers.forEach(fns => fns.forEach(({ onerror }) => callback(onerror, error)))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function report(error, match) {
|
|
125
|
+
let uncaught = false
|
|
126
|
+
subscribers.forEach((fns, event) => match(event) && fns.forEach(({ onerror }) =>
|
|
127
|
+
onerror ? callback(onerror, error) : uncaught = true
|
|
128
|
+
))
|
|
129
|
+
uncaught && callback(() => { throw error })
|
|
80
130
|
}
|
|
81
131
|
|
|
82
132
|
async function init(sql, slot, publications) {
|
|
@@ -100,18 +150,22 @@ export default function Subscribe(postgres, options) {
|
|
|
100
150
|
}
|
|
101
151
|
|
|
102
152
|
stream.on('data', data)
|
|
103
|
-
stream.on('error',
|
|
153
|
+
stream.on('error', reportConnection)
|
|
104
154
|
stream.on('close', sql.close)
|
|
105
155
|
|
|
106
|
-
|
|
156
|
+
// A walsender can miss the wakeup for a commit and sleep until its timeout; a status update wakes it.
|
|
157
|
+
const status = setInterval(() => stream.writable && pong(), statusInterval)
|
|
158
|
+
stream.on('close', () => clearInterval(status))
|
|
107
159
|
|
|
108
|
-
|
|
109
|
-
console.error('Unexpected error during logical streaming - reconnecting', e) // eslint-disable-line
|
|
110
|
-
}
|
|
160
|
+
return { stream, state: xs.state }
|
|
111
161
|
|
|
112
162
|
function data(x) {
|
|
113
163
|
if (x[0] === 0x77) {
|
|
114
|
-
|
|
164
|
+
try {
|
|
165
|
+
parse(x.subarray(25), state, sql.options.parsers, handle, options.transform)
|
|
166
|
+
} catch (error) {
|
|
167
|
+
skip(x.subarray(25), error)
|
|
168
|
+
}
|
|
115
169
|
} else if (x[0] === 0x6b && x[17]) {
|
|
116
170
|
state.lsn = x.subarray(1, 9)
|
|
117
171
|
pong()
|
|
@@ -120,12 +174,26 @@ export default function Subscribe(postgres, options) {
|
|
|
120
174
|
|
|
121
175
|
function handle(a, b) {
|
|
122
176
|
const path = b.relation.schema + '.' + b.relation.table
|
|
177
|
+
, key = b.relation.keys.length && '=' + b.relation.keys.map(x => a[x.name])
|
|
123
178
|
call('*', a, b)
|
|
124
179
|
call('*:' + path, a, b)
|
|
125
|
-
|
|
180
|
+
key && call('*:' + path + key, a, b)
|
|
126
181
|
call(b.command, a, b)
|
|
127
182
|
call(b.command + ':' + path, a, b)
|
|
128
|
-
|
|
183
|
+
key && call(b.command + ':' + path + key, a, b)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function skip(x, error) {
|
|
187
|
+
const command = commands[x[0]]
|
|
188
|
+
, relation = command && state[x.readUInt32BE(1)]
|
|
189
|
+
|
|
190
|
+
if (!relation)
|
|
191
|
+
throw error
|
|
192
|
+
|
|
193
|
+
const path = relation.schema + '.' + relation.table
|
|
194
|
+
, events = ['*', '*:' + path, command, command + ':' + path]
|
|
195
|
+
|
|
196
|
+
report(error, event => events.includes(event.split('=')[0]))
|
|
129
197
|
}
|
|
130
198
|
|
|
131
199
|
function pong() {
|
|
@@ -138,7 +206,7 @@ export default function Subscribe(postgres, options) {
|
|
|
138
206
|
}
|
|
139
207
|
|
|
140
208
|
function call(x, a, b) {
|
|
141
|
-
subscribers.has(x) && subscribers.get(x).forEach(({ fn }) => fn
|
|
209
|
+
subscribers.has(x) && subscribers.get(x).forEach(({ fn }) => callback(fn, a, b, x))
|
|
142
210
|
}
|
|
143
211
|
}
|
|
144
212
|
|
|
@@ -163,19 +231,24 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
163
231
|
let columnIndex = 0
|
|
164
232
|
, column
|
|
165
233
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
234
|
+
try {
|
|
235
|
+
while (i < x.length) {
|
|
236
|
+
column = r.columns[columnIndex++] = {
|
|
237
|
+
key: x[i++],
|
|
238
|
+
name: transform.column.from
|
|
239
|
+
? transform.column.from(x.toString('utf8', i, i = x.indexOf(0, i)))
|
|
240
|
+
: x.toString('utf8', i, i = x.indexOf(0, i)),
|
|
241
|
+
type: x.readUInt32BE(i += 1),
|
|
242
|
+
parser: parsers[x.readUInt32BE(i)],
|
|
243
|
+
atttypmod: x.readUInt32BE(i += 4)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
column.key && r.keys.push(column)
|
|
247
|
+
i += 4
|
|
175
248
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
249
|
+
} catch (error) {
|
|
250
|
+
r.error = error
|
|
251
|
+
r.failed = true
|
|
179
252
|
}
|
|
180
253
|
},
|
|
181
254
|
Y: () => { /* noop */ }, // Type
|
|
@@ -186,7 +259,7 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
186
259
|
},
|
|
187
260
|
I: x => { // Insert
|
|
188
261
|
let i = 1
|
|
189
|
-
const relation = state[x.readUInt32BE(i)]
|
|
262
|
+
const relation = decodable(state[x.readUInt32BE(i)])
|
|
190
263
|
const { row } = tuples(x, relation.columns, i += 7, transform)
|
|
191
264
|
|
|
192
265
|
handle(row, {
|
|
@@ -196,7 +269,7 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
196
269
|
},
|
|
197
270
|
D: x => { // Delete
|
|
198
271
|
let i = 1
|
|
199
|
-
const relation = state[x.readUInt32BE(i)]
|
|
272
|
+
const relation = decodable(state[x.readUInt32BE(i)])
|
|
200
273
|
i += 4
|
|
201
274
|
const key = x[i] === 75
|
|
202
275
|
handle(key || x[i] === 79
|
|
@@ -210,7 +283,7 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
210
283
|
},
|
|
211
284
|
U: x => { // Update
|
|
212
285
|
let i = 1
|
|
213
|
-
const relation = state[x.readUInt32BE(i)]
|
|
286
|
+
const relation = decodable(state[x.readUInt32BE(i)])
|
|
214
287
|
i += 4
|
|
215
288
|
const key = x[i] === 75
|
|
216
289
|
const xs = key || x[i] === 79
|
|
@@ -233,6 +306,13 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
233
306
|
}).reduce(char, {})[x[0]](x)
|
|
234
307
|
}
|
|
235
308
|
|
|
309
|
+
function decodable(relation) {
|
|
310
|
+
if (relation.failed)
|
|
311
|
+
throw relation.error
|
|
312
|
+
|
|
313
|
+
return relation
|
|
314
|
+
}
|
|
315
|
+
|
|
236
316
|
function tuples(x, columns, xi, transform) {
|
|
237
317
|
let type
|
|
238
318
|
, column
|
|
@@ -266,7 +346,7 @@ function tuples(x, columns, xi, transform) {
|
|
|
266
346
|
}
|
|
267
347
|
|
|
268
348
|
function parseEvent(x) {
|
|
269
|
-
const xs = x.match(/^(\*|insert|update|delete)?:?([
|
|
349
|
+
const xs = x.match(/^(\*|insert|update|delete)?:?([^.=]+(?:\.[^=]+)?)?=?(.+)?/i) || []
|
|
270
350
|
|
|
271
351
|
if (!xs)
|
|
272
352
|
throw new Error('Malformed subscribe pattern: ' + x)
|
package/cjs/src/connection.js
CHANGED
|
@@ -5,7 +5,7 @@ const Stream = require('stream')
|
|
|
5
5
|
const { performance } = require('perf_hooks')
|
|
6
6
|
|
|
7
7
|
const { stringify, handleValue, addArrayType } = require('./types.js')
|
|
8
|
-
const { Errors } = require('./errors.js')
|
|
8
|
+
const { Errors, callback } = require('./errors.js')
|
|
9
9
|
const Result = require('./result.js')
|
|
10
10
|
const Queue = require('./queue.js')
|
|
11
11
|
const clampedTimeout = require('./timeout.js')
|
|
@@ -13,7 +13,7 @@ const { SSLRequest, tlsConfig, cancelRequest } = require('./transport.js')
|
|
|
13
13
|
const { Query, CLOSE } = require('./query.js')
|
|
14
14
|
const b = require('./bytes.js')
|
|
15
15
|
|
|
16
|
-
module.exports = Connection
|
|
16
|
+
module.exports = { Connection }
|
|
17
17
|
|
|
18
18
|
let uid = 1
|
|
19
19
|
|
|
@@ -26,6 +26,8 @@ const Sync = b().S().end()
|
|
|
26
26
|
const Phase = { Closed: 0, Backoff: 1, Connecting: 2, Initializing: 3, Ready: 4, Draining: 5, Closing: 6 }
|
|
27
27
|
const phaseNames = Object.keys(Phase)
|
|
28
28
|
|
|
29
|
+
const endsAbortedState = /^\s*(rollback|abort)\b/i
|
|
30
|
+
|
|
29
31
|
const retryRoutines = new Set([
|
|
30
32
|
'FetchPreparedStatement',
|
|
31
33
|
'RevalidateCachedQuery',
|
|
@@ -110,6 +112,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
110
112
|
, chunk = null
|
|
111
113
|
, nonce = null
|
|
112
114
|
, query = null
|
|
115
|
+
, barrier = null
|
|
113
116
|
, final = null
|
|
114
117
|
|
|
115
118
|
const check = globalThis[Symbol.for('postgres.js:check')]
|
|
@@ -224,6 +227,9 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
224
227
|
owner: null,
|
|
225
228
|
get active() { return query ? 1 : 0 },
|
|
226
229
|
get pipelined() { return sent.length },
|
|
230
|
+
get accepting() { return accepting() },
|
|
231
|
+
get copying() { return stream !== null },
|
|
232
|
+
get copyHeld() { return stream !== null && !stream.writableEnded },
|
|
227
233
|
get acquiring() { return acquisition && !acquisition.owner.cancelled ? 1 : 0 },
|
|
228
234
|
count: 0,
|
|
229
235
|
id
|
|
@@ -268,8 +274,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
268
274
|
return !query && sent.length === 0
|
|
269
275
|
}
|
|
270
276
|
|
|
277
|
+
function accepting() {
|
|
278
|
+
return !query || (!barrier && sent.length < max_pipeline)
|
|
279
|
+
}
|
|
280
|
+
|
|
271
281
|
function backoffMs() {
|
|
272
|
-
return (
|
|
282
|
+
return backoffSeconds(backoff, options.shared.retries) * 1000
|
|
273
283
|
}
|
|
274
284
|
|
|
275
285
|
function standbyPass() {
|
|
@@ -446,7 +456,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
446
456
|
queryError(pending, err)
|
|
447
457
|
pending.cancelled && pending.cancelled.resolve()
|
|
448
458
|
}
|
|
449
|
-
query = results = errorResponse = chunk = nextWriteTimer = null
|
|
459
|
+
query = results = errorResponse = chunk = nextWriteTimer = barrier = null
|
|
450
460
|
result = new Result()
|
|
451
461
|
rows = 0
|
|
452
462
|
nonce = serverSignature = null
|
|
@@ -510,8 +520,10 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
510
520
|
}
|
|
511
521
|
|
|
512
522
|
function submit(q) {
|
|
513
|
-
if (stream)
|
|
514
|
-
|
|
523
|
+
if (stream) {
|
|
524
|
+
queryError(q, Errors.generic('COPY_IN_PROGRESS', 'You cannot execute queries during copy'))
|
|
525
|
+
return true
|
|
526
|
+
}
|
|
515
527
|
|
|
516
528
|
if (q.cancelled)
|
|
517
529
|
return true
|
|
@@ -525,17 +537,21 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
525
537
|
: (query = q, query.active = true)
|
|
526
538
|
|
|
527
539
|
build(q)
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
540
|
+
const written = write(toBuffer(q))
|
|
541
|
+
if (q.describeFirst || q.cursorFn || mayCopy(q))
|
|
542
|
+
barrier = q
|
|
543
|
+
return written && accepting()
|
|
532
544
|
} catch (error) {
|
|
533
545
|
sent.remove(q) || write(Sync)
|
|
534
546
|
queryError(q, error)
|
|
535
|
-
return
|
|
547
|
+
return accepting()
|
|
536
548
|
}
|
|
537
549
|
}
|
|
538
550
|
|
|
551
|
+
function mayCopy(q) {
|
|
552
|
+
return q.options.simple && /\bcopy\b/i.test(q.string)
|
|
553
|
+
}
|
|
554
|
+
|
|
539
555
|
function toBuffer(q) {
|
|
540
556
|
if (q.parameters.length >= 65534)
|
|
541
557
|
throw Errors.generic('MAX_PARAMETERS_EXCEEDED', 'Max number of parameters (65534) exceeded')
|
|
@@ -594,7 +610,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
594
610
|
? statements[q.signature]
|
|
595
611
|
: { string, types, name: q.prepare ? statementId + statementCount++ : '' }
|
|
596
612
|
|
|
597
|
-
typeof options.debug === 'function' && options.debug
|
|
613
|
+
typeof options.debug === 'function' && callback(options.debug, id, string, parameters, types)
|
|
598
614
|
}
|
|
599
615
|
|
|
600
616
|
function write(x, fn) {
|
|
@@ -765,18 +781,21 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
765
781
|
backendParameters[k] = v
|
|
766
782
|
if (options.parameters[k] !== v) {
|
|
767
783
|
options.parameters[k] = v
|
|
768
|
-
onparameter
|
|
784
|
+
callback(onparameter, k, v)
|
|
769
785
|
}
|
|
770
786
|
}
|
|
771
787
|
|
|
772
|
-
function ReadyForQuery() {
|
|
788
|
+
function ReadyForQuery(x) {
|
|
789
|
+
query === barrier && (barrier = null)
|
|
773
790
|
if (query) {
|
|
774
791
|
if (errorResponse) {
|
|
775
792
|
if (query.initialization)
|
|
776
793
|
return dispatch('initFailed', errorResponse)
|
|
794
|
+
query.prepared && retryRoutines.has(errorResponse.routine) && delete statements[query.signature]
|
|
777
795
|
query.retried
|
|
778
796
|
? errored(query.retried)
|
|
779
|
-
: query.prepared && retryRoutines.has(errorResponse.routine) && query.owner === connection.owner
|
|
797
|
+
: query.prepared && retryRoutines.has(errorResponse.routine) && query.owner === connection.owner && !barrier
|
|
798
|
+
&& (x[5] !== 69 || endsAbortedState.test(query.string))
|
|
780
799
|
? retry(query, errorResponse)
|
|
781
800
|
: errored(errorResponse)
|
|
782
801
|
} else {
|
|
@@ -1059,7 +1078,6 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1059
1078
|
}
|
|
1060
1079
|
|
|
1061
1080
|
function retry(q, error) {
|
|
1062
|
-
delete statements[q.signature]
|
|
1063
1081
|
q.retried = error
|
|
1064
1082
|
execute(q)
|
|
1065
1083
|
}
|
|
@@ -1070,7 +1088,8 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1070
1088
|
|
|
1071
1089
|
let index = 9
|
|
1072
1090
|
while (x[index++] !== 0);
|
|
1073
|
-
|
|
1091
|
+
callback(
|
|
1092
|
+
onnotify,
|
|
1074
1093
|
x.toString('utf8', 9, index - 1),
|
|
1075
1094
|
x.toString('utf8', index, x.length - 1)
|
|
1076
1095
|
)
|
|
@@ -1116,6 +1135,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1116
1135
|
}
|
|
1117
1136
|
})
|
|
1118
1137
|
query.resolve(stream)
|
|
1138
|
+
connection.owner && connection.owner.next()
|
|
1119
1139
|
}
|
|
1120
1140
|
|
|
1121
1141
|
function CopyOutResponse() {
|
|
@@ -1123,6 +1143,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1123
1143
|
read() { socket.resume() }
|
|
1124
1144
|
})
|
|
1125
1145
|
query.resolve(stream)
|
|
1146
|
+
connection.owner && connection.owner.next()
|
|
1126
1147
|
}
|
|
1127
1148
|
|
|
1128
1149
|
/* c8 ignore next 3 */
|
|
@@ -1145,6 +1166,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1145
1166
|
}
|
|
1146
1167
|
})
|
|
1147
1168
|
query.resolve(stream)
|
|
1169
|
+
connection.owner && connection.owner.next()
|
|
1148
1170
|
}
|
|
1149
1171
|
|
|
1150
1172
|
function CopyData(x) {
|
|
@@ -1157,10 +1179,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1157
1179
|
}
|
|
1158
1180
|
|
|
1159
1181
|
function NoticeResponse(x) {
|
|
1182
|
+
if (onnotice === false)
|
|
1183
|
+
return
|
|
1184
|
+
|
|
1160
1185
|
onnotice
|
|
1161
|
-
? onnotice
|
|
1186
|
+
? callback(onnotice, parseError(x))
|
|
1162
1187
|
: console.log(parseError(x)) // eslint-disable-line
|
|
1163
|
-
|
|
1164
1188
|
}
|
|
1165
1189
|
|
|
1166
1190
|
/* c8 ignore next 3 */
|
|
@@ -1311,3 +1335,19 @@ function timer(fn, seconds) {
|
|
|
1311
1335
|
fn.apply(null, args)
|
|
1312
1336
|
}
|
|
1313
1337
|
}
|
|
1338
|
+
|
|
1339
|
+
module.exports.defaultBackoff = defaultBackoff;function defaultBackoff(retries) {
|
|
1340
|
+
return (0.5 + Math.random() / 2) * Math.min(3 ** retries / 100, 20)
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
module.exports.backoffSeconds = backoffSeconds;function backoffSeconds(backoff, retries) {
|
|
1344
|
+
if (typeof backoff !== 'function')
|
|
1345
|
+
return backoff
|
|
1346
|
+
|
|
1347
|
+
try {
|
|
1348
|
+
return backoff(retries)
|
|
1349
|
+
} catch (e) {
|
|
1350
|
+
callback(() => { throw e })
|
|
1351
|
+
return defaultBackoff(retries)
|
|
1352
|
+
}
|
|
1353
|
+
}
|
package/cjs/src/errors.js
CHANGED
|
@@ -6,6 +6,14 @@ const PostgresError = module.exports.PostgresError = class PostgresError extends
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
module.exports.callback = callback;function callback(fn, ...args) {
|
|
10
|
+
try {
|
|
11
|
+
fn && fn(...args)
|
|
12
|
+
} catch (e) {
|
|
13
|
+
queueMicrotask(() => { throw e })
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
const Errors = module.exports.Errors = {
|
|
10
18
|
connection,
|
|
11
19
|
postgres,
|