@google-cloud/pubsub 3.4.1 → 3.5.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/CHANGELOG.md +14 -0
- package/README.md +1 -0
- package/build/protos/google/pubsub/v1/pubsub.proto +1 -1
- package/build/protos/google/pubsub/v1/schema.proto +1 -1
- package/build/protos/protos.json +1 -1
- package/build/src/debug.d.ts +21 -0
- package/build/src/debug.js +40 -0
- package/build/src/debug.js.map +1 -0
- package/build/src/exponential-retry.d.ts +7 -0
- package/build/src/exponential-retry.js +10 -0
- package/build/src/exponential-retry.js.map +1 -1
- package/build/src/index.d.ts +1 -0
- package/build/src/index.js +3 -1
- package/build/src/index.js.map +1 -1
- package/build/src/lease-manager.js +11 -1
- package/build/src/lease-manager.js.map +1 -1
- package/build/src/message-queues.d.ts +2 -1
- package/build/src/message-queues.js +10 -5
- package/build/src/message-queues.js.map +1 -1
- package/build/src/message-stream.d.ts +33 -22
- package/build/src/message-stream.js +132 -68
- package/build/src/message-stream.js.map +1 -1
- package/build/src/pull-retry.d.ts +2 -11
- package/build/src/pull-retry.js +4 -25
- package/build/src/pull-retry.js.map +1 -1
- package/build/src/subscriber.d.ts +9 -0
- package/build/src/subscriber.js +66 -6
- package/build/src/subscriber.js.map +1 -1
- package/build/src/subscription.d.ts +3 -3
- package/build/src/subscription.js +5 -5
- package/package.json +1 -1
|
@@ -22,6 +22,9 @@ const isStreamEnded = require("is-stream-ended");
|
|
|
22
22
|
const stream_1 = require("stream");
|
|
23
23
|
const pull_retry_1 = require("./pull-retry");
|
|
24
24
|
const default_options_1 = require("./default-options");
|
|
25
|
+
const temporal_1 = require("./temporal");
|
|
26
|
+
const exponential_retry_1 = require("./exponential-retry");
|
|
27
|
+
const debug_1 = require("./debug");
|
|
25
28
|
/*!
|
|
26
29
|
* Frequency to ping streams.
|
|
27
30
|
*/
|
|
@@ -37,6 +40,8 @@ const DEFAULT_OPTIONS = {
|
|
|
37
40
|
highWaterMark: 0,
|
|
38
41
|
maxStreams: default_options_1.defaultOptions.subscription.maxStreams,
|
|
39
42
|
timeout: 300000,
|
|
43
|
+
retryMinBackoff: temporal_1.Duration.from({ millis: 100 }),
|
|
44
|
+
retryMaxBackoff: temporal_1.Duration.from({ seconds: 60 }),
|
|
40
45
|
};
|
|
41
46
|
/**
|
|
42
47
|
* Error wrapper for gRPC status objects.
|
|
@@ -72,15 +77,6 @@ class ChannelError extends Error {
|
|
|
72
77
|
}
|
|
73
78
|
}
|
|
74
79
|
exports.ChannelError = ChannelError;
|
|
75
|
-
/**
|
|
76
|
-
* @typedef {object} MessageStreamOptions
|
|
77
|
-
* @property {number} [highWaterMark=0] Configures the Buffer level for all
|
|
78
|
-
* underlying streams. See
|
|
79
|
-
* {@link https://nodejs.org/en/docs/guides/backpressuring-in-streams/} for
|
|
80
|
-
* more details.
|
|
81
|
-
* @property {number} [maxStreams=5] Number of streaming connections to make.
|
|
82
|
-
* @property {number} [timeout=300000] Timeout for establishing a connection.
|
|
83
|
-
*/
|
|
84
80
|
/**
|
|
85
81
|
* Streaming class used to manage multiple StreamingPull requests.
|
|
86
82
|
*
|
|
@@ -95,10 +91,22 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
95
91
|
options = Object.assign({}, DEFAULT_OPTIONS, options);
|
|
96
92
|
super({ objectMode: true, highWaterMark: options.highWaterMark });
|
|
97
93
|
this._options = options;
|
|
98
|
-
this._retrier = new
|
|
99
|
-
|
|
94
|
+
this._retrier = new exponential_retry_1.ExponentialRetry(options.retryMinBackoff, // Filled by DEFAULT_OPTIONS
|
|
95
|
+
options.retryMaxBackoff);
|
|
96
|
+
this._streams = [];
|
|
97
|
+
for (let i = 0; i < options.maxStreams; i++) {
|
|
98
|
+
this._streams.push({});
|
|
99
|
+
}
|
|
100
100
|
this._subscriber = sub;
|
|
101
|
-
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Actually starts the stream setup and subscription pulls.
|
|
104
|
+
* This is separated so that others can properly wait on the promise.
|
|
105
|
+
*
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
async start() {
|
|
109
|
+
await this._fillStreamPool();
|
|
102
110
|
this._keepAliveHandle = setInterval(() => this._keepAlive(), KEEP_ALIVE_INTERVAL);
|
|
103
111
|
this._keepAliveHandle.unref();
|
|
104
112
|
}
|
|
@@ -111,9 +119,11 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
111
119
|
const request = {
|
|
112
120
|
streamAckDeadlineSeconds: deadline.totalOf('second'),
|
|
113
121
|
};
|
|
114
|
-
for (const
|
|
122
|
+
for (const tracker of this._streams) {
|
|
115
123
|
// We don't need a callback on this one, it's advisory.
|
|
116
|
-
stream
|
|
124
|
+
if (tracker.stream) {
|
|
125
|
+
tracker.stream.write(request);
|
|
126
|
+
}
|
|
117
127
|
}
|
|
118
128
|
}
|
|
119
129
|
/**
|
|
@@ -124,10 +134,15 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
124
134
|
* @private
|
|
125
135
|
*/
|
|
126
136
|
_destroy(error, callback) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
137
|
+
if (this._keepAliveHandle) {
|
|
138
|
+
clearInterval(this._keepAliveHandle);
|
|
139
|
+
}
|
|
140
|
+
this._retrier.close();
|
|
141
|
+
for (let i = 0; i < this._streams.length; i++) {
|
|
142
|
+
const tracker = this._streams[i];
|
|
143
|
+
if (tracker.stream) {
|
|
144
|
+
this._removeStream(i);
|
|
145
|
+
}
|
|
131
146
|
}
|
|
132
147
|
callback(error);
|
|
133
148
|
}
|
|
@@ -138,13 +153,22 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
138
153
|
*
|
|
139
154
|
* @param {stream} stream The StreamingPull stream.
|
|
140
155
|
*/
|
|
141
|
-
|
|
156
|
+
_replaceStream(index, stream) {
|
|
157
|
+
this._removeStream(index);
|
|
142
158
|
this._setHighWaterMark(stream);
|
|
143
|
-
this._streams
|
|
159
|
+
const tracker = this._streams[index];
|
|
160
|
+
tracker.stream = stream;
|
|
161
|
+
tracker.receivedStatus = false;
|
|
144
162
|
stream
|
|
145
|
-
.on('error', err => this._onError(
|
|
146
|
-
.once('status', status => this._onStatus(
|
|
147
|
-
.
|
|
163
|
+
.on('error', err => this._onError(index, err))
|
|
164
|
+
.once('status', status => this._onStatus(index, status))
|
|
165
|
+
.on('data', (data) => this._onData(index, data));
|
|
166
|
+
}
|
|
167
|
+
_onData(index, data) {
|
|
168
|
+
// Mark this stream as alive again. (reset backoff)
|
|
169
|
+
const tracker = this._streams[index];
|
|
170
|
+
this._retrier.reset(tracker);
|
|
171
|
+
this.emit('data', data);
|
|
148
172
|
}
|
|
149
173
|
/**
|
|
150
174
|
* Attempts to create and cache the desired number of StreamingPull requests.
|
|
@@ -157,6 +181,9 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
157
181
|
* @returns {Promise}
|
|
158
182
|
*/
|
|
159
183
|
async _fillStreamPool() {
|
|
184
|
+
if (this.destroyed) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
160
187
|
let client;
|
|
161
188
|
try {
|
|
162
189
|
client = await this._getClient();
|
|
@@ -165,9 +192,37 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
165
192
|
const err = e;
|
|
166
193
|
this.destroy(err);
|
|
167
194
|
}
|
|
195
|
+
const all = [];
|
|
196
|
+
for (let i = 0; i < this._streams.length; i++) {
|
|
197
|
+
all.push(this._fillOne(i, client));
|
|
198
|
+
}
|
|
199
|
+
await Promise.all(all);
|
|
200
|
+
try {
|
|
201
|
+
await this._waitForClientReady(client);
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
const err = e;
|
|
205
|
+
this.destroy(err);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async _fillOne(index, client) {
|
|
168
209
|
if (this.destroyed) {
|
|
169
210
|
return;
|
|
170
211
|
}
|
|
212
|
+
const tracker = this._streams[index];
|
|
213
|
+
if (tracker.stream) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (!client) {
|
|
217
|
+
try {
|
|
218
|
+
client = await this._getClient();
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
const err = e;
|
|
222
|
+
this.destroy(err);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
171
226
|
const deadline = Date.now() + PULL_TIMEOUT;
|
|
172
227
|
const request = {
|
|
173
228
|
subscription: this._subscriber.name,
|
|
@@ -179,19 +234,9 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
179
234
|
? 0
|
|
180
235
|
: this._subscriber.maxBytes,
|
|
181
236
|
};
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
this._addStream(stream);
|
|
186
|
-
stream.write(request);
|
|
187
|
-
}
|
|
188
|
-
try {
|
|
189
|
-
await this._waitForClientReady(client);
|
|
190
|
-
}
|
|
191
|
-
catch (e) {
|
|
192
|
-
const err = e;
|
|
193
|
-
this.destroy(err);
|
|
194
|
-
}
|
|
237
|
+
const stream = client.streamingPull({ deadline });
|
|
238
|
+
this._replaceStream(index, stream);
|
|
239
|
+
stream.write(request);
|
|
195
240
|
}
|
|
196
241
|
/**
|
|
197
242
|
* It is critical that we keep as few `PullResponse` objects in memory as
|
|
@@ -215,34 +260,42 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
215
260
|
* @private
|
|
216
261
|
*/
|
|
217
262
|
_keepAlive() {
|
|
218
|
-
this._streams.forEach(
|
|
219
|
-
//
|
|
220
|
-
// closed) but the stream hasn't drained yet
|
|
221
|
-
// result in a `write after end` error
|
|
222
|
-
if (!receivedStatus) {
|
|
223
|
-
stream.write({});
|
|
263
|
+
this._streams.forEach(tracker => {
|
|
264
|
+
// It's possible that a status event fires off (signaling the rpc being
|
|
265
|
+
// closed) but the stream hasn't drained yet. Writing to such a stream will
|
|
266
|
+
// result in a `write after end` error.
|
|
267
|
+
if (!tracker.receivedStatus && tracker.stream) {
|
|
268
|
+
tracker.stream.write({});
|
|
224
269
|
}
|
|
225
270
|
});
|
|
226
271
|
}
|
|
272
|
+
// Returns the number of tracked streams that contain an actual stream (good or not).
|
|
273
|
+
_activeStreams() {
|
|
274
|
+
return this._streams.reduce((p, t) => (t.stream ? 1 : 0) + p, 0);
|
|
275
|
+
}
|
|
227
276
|
/**
|
|
228
277
|
* Once the stream has nothing left to read, we'll remove it and attempt to
|
|
229
278
|
* refill our stream pool if needed.
|
|
230
279
|
*
|
|
231
280
|
* @private
|
|
232
281
|
*
|
|
233
|
-
* @param {
|
|
282
|
+
* @param {number} index The ended stream.
|
|
234
283
|
* @param {object} status The stream status.
|
|
235
284
|
*/
|
|
236
|
-
_onEnd(
|
|
237
|
-
this._removeStream(
|
|
238
|
-
if (
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
this.
|
|
285
|
+
_onEnd(index, status) {
|
|
286
|
+
this._removeStream(index);
|
|
287
|
+
if (pull_retry_1.PullRetry.retry(status)) {
|
|
288
|
+
this.emit('debug', new debug_1.DebugMessage(`Subscriber stream ${index} has ended with status ${status.code}; will be retried.`));
|
|
289
|
+
if (pull_retry_1.PullRetry.resetFailures(status)) {
|
|
290
|
+
this._retrier.reset(this._streams[index]);
|
|
291
|
+
}
|
|
292
|
+
this._retrier.retryLater(this._streams[index], () => {
|
|
293
|
+
this._fillOne(index);
|
|
294
|
+
});
|
|
244
295
|
}
|
|
245
|
-
else if (
|
|
296
|
+
else if (this._activeStreams() === 0) {
|
|
297
|
+
this.emit('debug', new debug_1.DebugMessage(`Subscriber stream ${index} has ended with status ${status.code}; will not be retried.`));
|
|
298
|
+
// No streams left, and nothing to retry.
|
|
246
299
|
this.destroy(new StatusError(status));
|
|
247
300
|
}
|
|
248
301
|
}
|
|
@@ -253,13 +306,14 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
253
306
|
*
|
|
254
307
|
* @private
|
|
255
308
|
*
|
|
256
|
-
* @param {
|
|
309
|
+
* @param {number} index The stream that errored.
|
|
257
310
|
* @param {Error} err The error.
|
|
258
311
|
*/
|
|
259
|
-
async _onError(
|
|
260
|
-
await (0, promisify_1.promisify)(
|
|
312
|
+
async _onError(index, err) {
|
|
313
|
+
await (0, promisify_1.promisify)(process.nextTick)();
|
|
261
314
|
const code = err.code;
|
|
262
|
-
const
|
|
315
|
+
const tracker = this._streams[index];
|
|
316
|
+
const receivedStatus = !tracker.stream || (tracker.stream && !tracker.receivedStatus);
|
|
263
317
|
if (typeof code !== 'number' || !receivedStatus) {
|
|
264
318
|
this.emit('error', err);
|
|
265
319
|
}
|
|
@@ -274,17 +328,22 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
274
328
|
* @param {stream} stream The stream that was closed.
|
|
275
329
|
* @param {object} status The status message stating why it was closed.
|
|
276
330
|
*/
|
|
277
|
-
_onStatus(
|
|
331
|
+
_onStatus(index, status) {
|
|
278
332
|
if (this.destroyed) {
|
|
279
333
|
return;
|
|
280
334
|
}
|
|
281
|
-
this._streams
|
|
282
|
-
|
|
283
|
-
|
|
335
|
+
const tracker = this._streams[index];
|
|
336
|
+
tracker.receivedStatus = true;
|
|
337
|
+
if (!tracker.stream) {
|
|
338
|
+
// This shouldn't really happen, but in case wires get crossed.
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
if (isStreamEnded(tracker.stream)) {
|
|
342
|
+
this._onEnd(index, status);
|
|
284
343
|
}
|
|
285
344
|
else {
|
|
286
|
-
stream.once('end', () => this._onEnd(
|
|
287
|
-
stream.push(null);
|
|
345
|
+
tracker.stream.once('end', () => this._onEnd(index, status));
|
|
346
|
+
tracker.stream.push(null);
|
|
288
347
|
}
|
|
289
348
|
}
|
|
290
349
|
/**
|
|
@@ -292,14 +351,19 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
292
351
|
*
|
|
293
352
|
* @private
|
|
294
353
|
*
|
|
295
|
-
* @param {
|
|
354
|
+
* @param {number} index The stream to remove.
|
|
296
355
|
*/
|
|
297
|
-
_removeStream(
|
|
298
|
-
|
|
299
|
-
|
|
356
|
+
_removeStream(index) {
|
|
357
|
+
const tracker = this._streams[index];
|
|
358
|
+
if (tracker.stream) {
|
|
359
|
+
tracker.stream.unpipe(this);
|
|
360
|
+
tracker.stream.cancel();
|
|
361
|
+
tracker.stream = undefined;
|
|
362
|
+
tracker.receivedStatus = undefined;
|
|
363
|
+
}
|
|
300
364
|
}
|
|
301
365
|
/**
|
|
302
|
-
* Neither gRPC
|
|
366
|
+
* Neither gRPC nor gax allow for the highWaterMark option to be specified.
|
|
303
367
|
* However using the default value (16) it is possible to end up with a lot of
|
|
304
368
|
* PullResponse objects stored in internal buffers. If this were to happen
|
|
305
369
|
* and the client were slow to process messages, we could potentially see a
|
|
@@ -315,7 +379,7 @@ class MessageStream extends stream_1.PassThrough {
|
|
|
315
379
|
stream._readableState.highWaterMark = this._options.highWaterMark;
|
|
316
380
|
}
|
|
317
381
|
/**
|
|
318
|
-
* Promisified version of
|
|
382
|
+
* Promisified version of gRPC's Client#waitForReady function.
|
|
319
383
|
*
|
|
320
384
|
* @private
|
|
321
385
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-stream.js","sourceRoot":"","sources":["../../src/message-stream.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH,uDAAkD;AAClD,2CAA4C;AAC5C,iDAAiD;AACjD,mCAAmC;AAEnC,6CAAuC;AAGvC,uDAAiD;
|
|
1
|
+
{"version":3,"file":"message-stream.js","sourceRoot":"","sources":["../../src/message-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,16 +26,6 @@ export declare const RETRY_CODES: grpc.status[];
|
|
|
26
26
|
* @private
|
|
27
27
|
*/
|
|
28
28
|
export declare class PullRetry {
|
|
29
|
-
private failures;
|
|
30
|
-
/**
|
|
31
|
-
* Generates a timeout that can be used for applying a backoff based on the
|
|
32
|
-
* current number of failed requests.
|
|
33
|
-
*
|
|
34
|
-
* @see {@link https://cloud.google.com/iot/docs/how-tos/exponential-backoff}
|
|
35
|
-
* @private
|
|
36
|
-
* @returns {number}
|
|
37
|
-
*/
|
|
38
|
-
createTimeout(): number;
|
|
39
29
|
/**
|
|
40
30
|
* Determines if a request grpc.status should be retried.
|
|
41
31
|
*
|
|
@@ -49,5 +39,6 @@ export declare class PullRetry {
|
|
|
49
39
|
* @param {object} grpc.status The request grpc.status.
|
|
50
40
|
* @returns {boolean}
|
|
51
41
|
*/
|
|
52
|
-
retry(err: grpc.StatusObject): boolean;
|
|
42
|
+
static retry(err: grpc.StatusObject): boolean;
|
|
43
|
+
static resetFailures(err: grpc.StatusObject): boolean;
|
|
53
44
|
}
|
package/build/src/pull-retry.js
CHANGED
|
@@ -36,23 +36,6 @@ exports.RETRY_CODES = [
|
|
|
36
36
|
* @private
|
|
37
37
|
*/
|
|
38
38
|
class PullRetry {
|
|
39
|
-
constructor() {
|
|
40
|
-
this.failures = 0;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Generates a timeout that can be used for applying a backoff based on the
|
|
44
|
-
* current number of failed requests.
|
|
45
|
-
*
|
|
46
|
-
* @see {@link https://cloud.google.com/iot/docs/how-tos/exponential-backoff}
|
|
47
|
-
* @private
|
|
48
|
-
* @returns {number}
|
|
49
|
-
*/
|
|
50
|
-
createTimeout() {
|
|
51
|
-
if (this.failures === 0) {
|
|
52
|
-
return 0;
|
|
53
|
-
}
|
|
54
|
-
return Math.pow(2, this.failures) * 1000 + Math.floor(Math.random() * 1000);
|
|
55
|
-
}
|
|
56
39
|
/**
|
|
57
40
|
* Determines if a request grpc.status should be retried.
|
|
58
41
|
*
|
|
@@ -66,14 +49,7 @@ class PullRetry {
|
|
|
66
49
|
* @param {object} grpc.status The request grpc.status.
|
|
67
50
|
* @returns {boolean}
|
|
68
51
|
*/
|
|
69
|
-
retry(err) {
|
|
70
|
-
if (err.code === google_gax_1.grpc.status.OK ||
|
|
71
|
-
err.code === google_gax_1.grpc.status.DEADLINE_EXCEEDED) {
|
|
72
|
-
this.failures = 0;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
this.failures += 1;
|
|
76
|
-
}
|
|
52
|
+
static retry(err) {
|
|
77
53
|
if (err.code === google_gax_1.grpc.status.UNAVAILABLE &&
|
|
78
54
|
err.details &&
|
|
79
55
|
err.details.match(/Server shutdownNow invoked/)) {
|
|
@@ -81,6 +57,9 @@ class PullRetry {
|
|
|
81
57
|
}
|
|
82
58
|
return exports.RETRY_CODES.includes(err.code);
|
|
83
59
|
}
|
|
60
|
+
static resetFailures(err) {
|
|
61
|
+
return (err.code === google_gax_1.grpc.status.OK || err.code === google_gax_1.grpc.status.DEADLINE_EXCEEDED);
|
|
62
|
+
}
|
|
84
63
|
}
|
|
85
64
|
exports.PullRetry = PullRetry;
|
|
86
65
|
//# sourceMappingURL=pull-retry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull-retry.js","sourceRoot":"","sources":["../../src/pull-retry.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;GAcG;AACH,2CAAgC;AAEhC;;GAEG;AACU,QAAA,WAAW,GAAkB;IACxC,iBAAI,CAAC,MAAM,CAAC,iBAAiB;IAC7B,iBAAI,CAAC,MAAM,CAAC,kBAAkB;IAC9B,iBAAI,CAAC,MAAM,CAAC,OAAO;IACnB,iBAAI,CAAC,MAAM,CAAC,QAAQ;IACpB,iBAAI,CAAC,MAAM,CAAC,WAAW;IACvB,iBAAI,CAAC,MAAM,CAAC,SAAS;CACtB,CAAC;AAEF;;;;;;GAMG;AACH,MAAa,SAAS;
|
|
1
|
+
{"version":3,"file":"pull-retry.js","sourceRoot":"","sources":["../../src/pull-retry.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;GAcG;AACH,2CAAgC;AAEhC;;GAEG;AACU,QAAA,WAAW,GAAkB;IACxC,iBAAI,CAAC,MAAM,CAAC,iBAAiB;IAC7B,iBAAI,CAAC,MAAM,CAAC,kBAAkB;IAC9B,iBAAI,CAAC,MAAM,CAAC,OAAO;IACnB,iBAAI,CAAC,MAAM,CAAC,QAAQ;IACpB,iBAAI,CAAC,MAAM,CAAC,WAAW;IACvB,iBAAI,CAAC,MAAM,CAAC,SAAS;CACtB,CAAC;AAEF;;;;;;GAMG;AACH,MAAa,SAAS;IACpB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,KAAK,CAAC,GAAsB;QACjC,IACE,GAAG,CAAC,IAAI,KAAK,iBAAI,CAAC,MAAM,CAAC,WAAW;YACpC,GAAG,CAAC,OAAO;YACX,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,EAC/C;YACA,OAAO,IAAI,CAAC;SACb;QAED,OAAO,mBAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,GAAsB;QACzC,OAAO,CACL,GAAG,CAAC,IAAI,KAAK,iBAAI,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAI,CAAC,MAAM,CAAC,iBAAiB,CAC1E,CAAC;IACJ,CAAC;CACF;AA/BD,8BA+BC"}
|
|
@@ -85,6 +85,7 @@ export declare class Message {
|
|
|
85
85
|
private _handled;
|
|
86
86
|
private _length;
|
|
87
87
|
private _subscriber;
|
|
88
|
+
private _ackFailed?;
|
|
88
89
|
/**
|
|
89
90
|
* @hideconstructor
|
|
90
91
|
*
|
|
@@ -98,6 +99,13 @@ export declare class Message {
|
|
|
98
99
|
* @type {number}
|
|
99
100
|
*/
|
|
100
101
|
get length(): number;
|
|
102
|
+
/**
|
|
103
|
+
* Sets this message's exactly once delivery acks to permanent failure. This is
|
|
104
|
+
* meant for internal library use only.
|
|
105
|
+
*
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
ackFailed(error: AckError): void;
|
|
101
109
|
/**
|
|
102
110
|
* Acknowledges the message.
|
|
103
111
|
*
|
|
@@ -367,6 +375,7 @@ export declare class Subscriber extends EventEmitter {
|
|
|
367
375
|
* @private
|
|
368
376
|
*/
|
|
369
377
|
private _onData;
|
|
378
|
+
private _discardMessage;
|
|
370
379
|
/**
|
|
371
380
|
* Returns a promise that will resolve once all pending requests have settled.
|
|
372
381
|
*
|
package/build/src/subscriber.js
CHANGED
|
@@ -165,6 +165,15 @@ class Message {
|
|
|
165
165
|
get length() {
|
|
166
166
|
return this._length;
|
|
167
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Sets this message's exactly once delivery acks to permanent failure. This is
|
|
170
|
+
* meant for internal library use only.
|
|
171
|
+
*
|
|
172
|
+
* @private
|
|
173
|
+
*/
|
|
174
|
+
ackFailed(error) {
|
|
175
|
+
this._ackFailed = error;
|
|
176
|
+
}
|
|
168
177
|
/**
|
|
169
178
|
* Acknowledges the message.
|
|
170
179
|
*
|
|
@@ -197,9 +206,18 @@ class Message {
|
|
|
197
206
|
this.ack();
|
|
198
207
|
return exports.AckResponses.Success;
|
|
199
208
|
}
|
|
209
|
+
if (this._ackFailed) {
|
|
210
|
+
throw this._ackFailed;
|
|
211
|
+
}
|
|
200
212
|
if (!this._handled) {
|
|
201
213
|
this._handled = true;
|
|
202
|
-
|
|
214
|
+
try {
|
|
215
|
+
return await this._subscriber.ackWithResponse(this);
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
this.ackFailed(e);
|
|
219
|
+
throw e;
|
|
220
|
+
}
|
|
203
221
|
}
|
|
204
222
|
else {
|
|
205
223
|
return exports.AckResponses.Invalid;
|
|
@@ -228,8 +246,17 @@ class Message {
|
|
|
228
246
|
this.modAck(deadline);
|
|
229
247
|
return exports.AckResponses.Success;
|
|
230
248
|
}
|
|
249
|
+
if (this._ackFailed) {
|
|
250
|
+
throw this._ackFailed;
|
|
251
|
+
}
|
|
231
252
|
if (!this._handled) {
|
|
232
|
-
|
|
253
|
+
try {
|
|
254
|
+
return await this._subscriber.modAckWithResponse(this, deadline);
|
|
255
|
+
}
|
|
256
|
+
catch (e) {
|
|
257
|
+
this.ackFailed(e);
|
|
258
|
+
throw e;
|
|
259
|
+
}
|
|
233
260
|
}
|
|
234
261
|
else {
|
|
235
262
|
return exports.AckResponses.Invalid;
|
|
@@ -268,9 +295,18 @@ class Message {
|
|
|
268
295
|
this.nack();
|
|
269
296
|
return exports.AckResponses.Success;
|
|
270
297
|
}
|
|
298
|
+
if (this._ackFailed) {
|
|
299
|
+
throw this._ackFailed;
|
|
300
|
+
}
|
|
271
301
|
if (!this._handled) {
|
|
272
302
|
this._handled = true;
|
|
273
|
-
|
|
303
|
+
try {
|
|
304
|
+
return await this._subscriber.nackWithResponse(this);
|
|
305
|
+
}
|
|
306
|
+
catch (e) {
|
|
307
|
+
this.ackFailed(e);
|
|
308
|
+
throw e;
|
|
309
|
+
}
|
|
274
310
|
}
|
|
275
311
|
else {
|
|
276
312
|
return exports.AckResponses.Invalid;
|
|
@@ -541,12 +577,16 @@ class Subscriber extends events_1.EventEmitter {
|
|
|
541
577
|
this._stream = new message_stream_1.MessageStream(this, streamingOptions);
|
|
542
578
|
this._stream
|
|
543
579
|
.on('error', err => this.emit('error', err))
|
|
544
|
-
.on('debug',
|
|
580
|
+
.on('debug', msg => this.emit('debug', msg))
|
|
545
581
|
.on('data', (data) => this._onData(data))
|
|
546
582
|
.once('close', () => this.close());
|
|
547
583
|
this._inventory
|
|
548
584
|
.on('full', () => this._stream.pause())
|
|
549
585
|
.on('free', () => this._stream.resume());
|
|
586
|
+
this._stream.start().catch(err => {
|
|
587
|
+
this.emit('error', err);
|
|
588
|
+
this.close();
|
|
589
|
+
});
|
|
550
590
|
this.isOpen = true;
|
|
551
591
|
}
|
|
552
592
|
/**
|
|
@@ -655,8 +695,24 @@ class Subscriber extends events_1.EventEmitter {
|
|
|
655
695
|
const message = new Message(this, data);
|
|
656
696
|
const span = this._constructSpan(message);
|
|
657
697
|
if (this.isOpen) {
|
|
658
|
-
|
|
659
|
-
|
|
698
|
+
if (this.isExactlyOnceDelivery) {
|
|
699
|
+
// For exactly-once delivery, we must validate that we got a valid
|
|
700
|
+
// lease on the message before actually leasing it.
|
|
701
|
+
message
|
|
702
|
+
.modAckWithResponse(this.ackDeadline)
|
|
703
|
+
.then(() => {
|
|
704
|
+
this._inventory.add(message);
|
|
705
|
+
})
|
|
706
|
+
.catch(() => {
|
|
707
|
+
// Temporary failures will retry, so if an error reaches us
|
|
708
|
+
// here, that means a permanent failure. Silently drop these.
|
|
709
|
+
this._discardMessage(message);
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
message.modAck(this.ackDeadline);
|
|
714
|
+
this._inventory.add(message);
|
|
715
|
+
}
|
|
660
716
|
}
|
|
661
717
|
else {
|
|
662
718
|
message.nack();
|
|
@@ -666,6 +722,10 @@ class Subscriber extends events_1.EventEmitter {
|
|
|
666
722
|
}
|
|
667
723
|
}
|
|
668
724
|
}
|
|
725
|
+
// Internal: This is here to provide a hook for unit testing, at least for now.
|
|
726
|
+
_discardMessage(message) {
|
|
727
|
+
message;
|
|
728
|
+
}
|
|
669
729
|
/**
|
|
670
730
|
* Returns a promise that will resolve once all pending requests have settled.
|
|
671
731
|
*
|