@google-cloud/pubsub 3.1.0 → 3.2.0
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 +25 -0
- package/README.md +2 -0
- package/build/protos/protos.d.ts +689 -2
- package/build/protos/protos.js +3162 -1244
- package/build/protos/protos.json +17 -0
- package/build/src/ack-metadata.d.ts +29 -0
- package/build/src/ack-metadata.js +93 -0
- package/build/src/ack-metadata.js.map +1 -0
- package/build/src/exponential-retry.d.ts +66 -0
- package/build/src/exponential-retry.js +138 -0
- package/build/src/exponential-retry.js.map +1 -0
- package/build/src/index.d.ts +1 -1
- package/build/src/index.js +3 -1
- package/build/src/index.js.map +1 -1
- package/build/src/message-queues.d.ts +85 -12
- package/build/src/message-queues.js +279 -19
- package/build/src/message-queues.js.map +1 -1
- package/build/src/message-stream.d.ts +7 -0
- package/build/src/message-stream.js +14 -0
- package/build/src/message-stream.js.map +1 -1
- package/build/src/publisher/index.js +12 -3
- package/build/src/publisher/index.js.map +1 -1
- package/build/src/publisher/message-queues.d.ts +2 -0
- package/build/src/publisher/message-queues.js +16 -1
- package/build/src/publisher/message-queues.js.map +1 -1
- package/build/src/subscriber.d.ts +86 -6
- package/build/src/subscriber.js +168 -26
- package/build/src/subscriber.js.map +1 -1
- package/build/src/subscription.d.ts +1 -1
- package/build/src/subscription.js +4 -1
- package/build/src/subscription.js.map +1 -1
- package/build/src/util.d.ts +6 -0
- package/build/src/util.js +13 -1
- package/build/src/util.js.map +1 -1
- package/build/src/v1/publisher_client.d.ts +11 -4
- package/build/src/v1/publisher_client.js +62 -39
- package/build/src/v1/publisher_client.js.map +1 -1
- package/build/src/v1/schema_service_client.d.ts +11 -4
- package/build/src/v1/schema_service_client.js +40 -24
- package/build/src/v1/schema_service_client.js.map +1 -1
- package/build/src/v1/subscriber_client.d.ts +10 -3
- package/build/src/v1/subscriber_client.js +75 -48
- package/build/src/v1/subscriber_client.js.map +1 -1
- package/package.json +6 -5
package/build/protos/protos.json
CHANGED
|
@@ -2064,6 +2064,10 @@
|
|
|
2064
2064
|
"syntax": {
|
|
2065
2065
|
"type": "string",
|
|
2066
2066
|
"id": 12
|
|
2067
|
+
},
|
|
2068
|
+
"edition": {
|
|
2069
|
+
"type": "string",
|
|
2070
|
+
"id": 13
|
|
2067
2071
|
}
|
|
2068
2072
|
}
|
|
2069
2073
|
},
|
|
@@ -2891,6 +2895,19 @@
|
|
|
2891
2895
|
"end": {
|
|
2892
2896
|
"type": "int32",
|
|
2893
2897
|
"id": 4
|
|
2898
|
+
},
|
|
2899
|
+
"semantic": {
|
|
2900
|
+
"type": "Semantic",
|
|
2901
|
+
"id": 5
|
|
2902
|
+
}
|
|
2903
|
+
},
|
|
2904
|
+
"nested": {
|
|
2905
|
+
"Semantic": {
|
|
2906
|
+
"values": {
|
|
2907
|
+
"NONE": 0,
|
|
2908
|
+
"SET": 1,
|
|
2909
|
+
"ALIAS": 2
|
|
2910
|
+
}
|
|
2894
2911
|
}
|
|
2895
2912
|
}
|
|
2896
2913
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { GoogleError, Status } from 'google-gax';
|
|
2
|
+
import { AckResponse } from './subscriber';
|
|
3
|
+
/**
|
|
4
|
+
* Contains information about ack responses that may be used to build
|
|
5
|
+
* responses to user ack calls.
|
|
6
|
+
*
|
|
7
|
+
* @private
|
|
8
|
+
*/
|
|
9
|
+
export interface AckErrorInfo {
|
|
10
|
+
transient: boolean;
|
|
11
|
+
response?: AckResponse;
|
|
12
|
+
rawErrorCode?: string;
|
|
13
|
+
grpcErrorCode?: Status;
|
|
14
|
+
}
|
|
15
|
+
export declare type AckErrorCodes = Map<string, AckErrorInfo>;
|
|
16
|
+
/**
|
|
17
|
+
* Processes the raw RPC information when sending a batch of acks
|
|
18
|
+
* to the Pub/Sub service.
|
|
19
|
+
*
|
|
20
|
+
* @private
|
|
21
|
+
*/
|
|
22
|
+
export declare function processAckErrorInfo(rpcError: GoogleError): AckErrorCodes;
|
|
23
|
+
/**
|
|
24
|
+
* For a completely failed RPC call, this will find the appropriate
|
|
25
|
+
* error information to return to an ack() caller.
|
|
26
|
+
*
|
|
27
|
+
* @private
|
|
28
|
+
*/
|
|
29
|
+
export declare function processAckRpcError(grpcCode: Status): AckErrorInfo;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2022 Google LLC
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.processAckRpcError = exports.processAckErrorInfo = void 0;
|
|
17
|
+
const google_gax_1 = require("google-gax");
|
|
18
|
+
const subscriber_1 = require("./subscriber");
|
|
19
|
+
const permanentFailureInvalidAckId = 'PERMANENT_FAILURE_INVALID_ACK_ID';
|
|
20
|
+
const transientFailurePrefix = 'TRANSIENT_';
|
|
21
|
+
// If we get these as RPC errors, they will trigger a retry.
|
|
22
|
+
const exactlyOnceDeliveryTemporaryRetryErrors = [
|
|
23
|
+
google_gax_1.Status.DEADLINE_EXCEEDED,
|
|
24
|
+
google_gax_1.Status.RESOURCE_EXHAUSTED,
|
|
25
|
+
google_gax_1.Status.ABORTED,
|
|
26
|
+
google_gax_1.Status.INTERNAL,
|
|
27
|
+
google_gax_1.Status.UNAVAILABLE,
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* Processes the raw RPC information when sending a batch of acks
|
|
31
|
+
* to the Pub/Sub service.
|
|
32
|
+
*
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
35
|
+
function processAckErrorInfo(rpcError) {
|
|
36
|
+
const ret = new Map();
|
|
37
|
+
if (!rpcError.errorInfoMetadata) {
|
|
38
|
+
return ret;
|
|
39
|
+
}
|
|
40
|
+
// The typing for errorInfoMetadata is currently incorrect.
|
|
41
|
+
const metadata = rpcError.errorInfoMetadata;
|
|
42
|
+
for (const ackId of Object.getOwnPropertyNames(metadata)) {
|
|
43
|
+
const code = metadata[ackId];
|
|
44
|
+
if (code === permanentFailureInvalidAckId) {
|
|
45
|
+
ret.set(ackId, {
|
|
46
|
+
transient: false,
|
|
47
|
+
response: subscriber_1.AckResponses.Invalid,
|
|
48
|
+
rawErrorCode: code,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else if (code.startsWith(transientFailurePrefix)) {
|
|
52
|
+
ret.set(ackId, {
|
|
53
|
+
transient: true,
|
|
54
|
+
rawErrorCode: code,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
ret.set(ackId, {
|
|
59
|
+
transient: false,
|
|
60
|
+
response: subscriber_1.AckResponses.Other,
|
|
61
|
+
rawErrorCode: code,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return ret;
|
|
66
|
+
}
|
|
67
|
+
exports.processAckErrorInfo = processAckErrorInfo;
|
|
68
|
+
/**
|
|
69
|
+
* For a completely failed RPC call, this will find the appropriate
|
|
70
|
+
* error information to return to an ack() caller.
|
|
71
|
+
*
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
function processAckRpcError(grpcCode) {
|
|
75
|
+
const ackError = {
|
|
76
|
+
transient: exactlyOnceDeliveryTemporaryRetryErrors.includes(grpcCode),
|
|
77
|
+
grpcErrorCode: grpcCode,
|
|
78
|
+
};
|
|
79
|
+
switch (grpcCode) {
|
|
80
|
+
case google_gax_1.Status.PERMISSION_DENIED:
|
|
81
|
+
ackError.response = subscriber_1.AckResponses.PermissionDenied;
|
|
82
|
+
break;
|
|
83
|
+
case google_gax_1.Status.FAILED_PRECONDITION:
|
|
84
|
+
ackError.response = subscriber_1.AckResponses.FailedPrecondition;
|
|
85
|
+
break;
|
|
86
|
+
default:
|
|
87
|
+
ackError.response = subscriber_1.AckResponses.Other;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
return ackError;
|
|
91
|
+
}
|
|
92
|
+
exports.processAckRpcError = processAckRpcError;
|
|
93
|
+
//# sourceMappingURL=ack-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ack-metadata.js","sourceRoot":"","sources":["../../src/ack-metadata.ts"],"names":[],"mappings":";AAAA,4BAA4B;AAC5B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,kDAAkD;AAClD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;;AAEjC,2CAA+C;AAC/C,6CAAuD;AAEvD,MAAM,4BAA4B,GAAG,kCAAkC,CAAC;AACxE,MAAM,sBAAsB,GAAG,YAAY,CAAC;AAE5C,4DAA4D;AAC5D,MAAM,uCAAuC,GAAG;IAC9C,mBAAM,CAAC,iBAAiB;IACxB,mBAAM,CAAC,kBAAkB;IACzB,mBAAM,CAAC,OAAO;IACd,mBAAM,CAAC,QAAQ;IACf,mBAAM,CAAC,WAAW;CACnB,CAAC;AAwBF;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,QAAqB;IACvD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAwB,CAAC;IAE5C,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE;QAC/B,OAAO,GAAG,CAAC;KACZ;IAED,2DAA2D;IAC3D,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAmC,CAAC;IAE9D,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE;QACxD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE7B,IAAI,IAAI,KAAK,4BAA4B,EAAE;YACzC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE;gBACb,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,yBAAY,CAAC,OAAO;gBAC9B,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;SACJ;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE;YAClD,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE;gBACb,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;SACJ;aAAM;YACL,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE;gBACb,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,yBAAY,CAAC,KAAK;gBAC5B,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;SACJ;KACF;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAlCD,kDAkCC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,QAAgB;IACjD,MAAM,QAAQ,GAAiB;QAC7B,SAAS,EAAE,uCAAuC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACrE,aAAa,EAAE,QAAQ;KACxB,CAAC;IACF,QAAQ,QAAQ,EAAE;QAChB,KAAK,mBAAM,CAAC,iBAAiB;YAC3B,QAAQ,CAAC,QAAQ,GAAG,yBAAY,CAAC,gBAAgB,CAAC;YAClD,MAAM;QACR,KAAK,mBAAM,CAAC,mBAAmB;YAC7B,QAAQ,CAAC,QAAQ,GAAG,yBAAY,CAAC,kBAAkB,CAAC;YACpD,MAAM;QACR;YACE,QAAQ,CAAC,QAAQ,GAAG,yBAAY,CAAC,KAAK,CAAC;YACvC,MAAM;KACT;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAlBD,gDAkBC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Duration } from './temporal';
|
|
2
|
+
/**
|
|
3
|
+
* This interface specifies what we'll add to retried items in order
|
|
4
|
+
* to track them through the exponential backoff.
|
|
5
|
+
*
|
|
6
|
+
* @private
|
|
7
|
+
*/
|
|
8
|
+
export interface RetriedItem<T> {
|
|
9
|
+
retryInfo?: RetryInfo<T>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* These items will go inside the added retry metadata.
|
|
13
|
+
*
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
export interface RetryInfo<T> {
|
|
17
|
+
firstRetry: number;
|
|
18
|
+
nextRetry: number;
|
|
19
|
+
multiplier: number;
|
|
20
|
+
callback: RetryCallback<T>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Users of this class will pass in a callback in this form when
|
|
24
|
+
* an item is ready to be retried. The item must be placed
|
|
25
|
+
* back on the queue if it needs to be retried again.
|
|
26
|
+
*
|
|
27
|
+
* @private
|
|
28
|
+
*/
|
|
29
|
+
export interface RetryCallback<T> {
|
|
30
|
+
(item: T, totalTime: Duration): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Provides a helper that will manage your retries using the "truncated
|
|
34
|
+
* exponential backoff" strategy.
|
|
35
|
+
*
|
|
36
|
+
* Most of the pieces of this library are doing retries via gax, but for
|
|
37
|
+
* exactly-once delivery, we have some things where gRPC failures won't
|
|
38
|
+
* take care of it.
|
|
39
|
+
*
|
|
40
|
+
* @private
|
|
41
|
+
*/
|
|
42
|
+
export declare class ExponentialRetry<T> {
|
|
43
|
+
private _items;
|
|
44
|
+
private _backoffMs;
|
|
45
|
+
private _maxBackoffMs;
|
|
46
|
+
private _timer?;
|
|
47
|
+
constructor(backoff: Duration, maxBackoff: Duration);
|
|
48
|
+
/**
|
|
49
|
+
* Shut down all operations/timers/etc and return a list of
|
|
50
|
+
* items that were still pending retry.
|
|
51
|
+
*
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
close(): T[];
|
|
55
|
+
/**
|
|
56
|
+
* Place an item on the retry queue. It's important that it's the
|
|
57
|
+
* same exact item that was already on the queue, if it's being retried
|
|
58
|
+
* more than once.
|
|
59
|
+
*
|
|
60
|
+
* @private
|
|
61
|
+
*/
|
|
62
|
+
retryLater(item: T, callback: RetryCallback<T>): void;
|
|
63
|
+
private randomizeDelta;
|
|
64
|
+
private doRetries;
|
|
65
|
+
private scheduleRetry;
|
|
66
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2022 Google LLC
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ExponentialRetry = void 0;
|
|
17
|
+
const heap_js_1 = require("heap-js");
|
|
18
|
+
const temporal_1 = require("./temporal");
|
|
19
|
+
// Compare function for Heap so we can use it as a priority queue.
|
|
20
|
+
function comparator(a, b) {
|
|
21
|
+
return a.retryInfo.nextRetry - b.retryInfo.nextRetry;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Provides a helper that will manage your retries using the "truncated
|
|
25
|
+
* exponential backoff" strategy.
|
|
26
|
+
*
|
|
27
|
+
* Most of the pieces of this library are doing retries via gax, but for
|
|
28
|
+
* exactly-once delivery, we have some things where gRPC failures won't
|
|
29
|
+
* take care of it.
|
|
30
|
+
*
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
class ExponentialRetry {
|
|
34
|
+
constructor(backoff, maxBackoff) {
|
|
35
|
+
this._items = new heap_js_1.default((comparator));
|
|
36
|
+
this._backoffMs = backoff.totalOf('millisecond');
|
|
37
|
+
this._maxBackoffMs = maxBackoff.totalOf('millisecond');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Shut down all operations/timers/etc and return a list of
|
|
41
|
+
* items that were still pending retry.
|
|
42
|
+
*
|
|
43
|
+
* @private
|
|
44
|
+
*/
|
|
45
|
+
close() {
|
|
46
|
+
if (this._timer) {
|
|
47
|
+
clearTimeout(this._timer);
|
|
48
|
+
}
|
|
49
|
+
const leftovers = this._items.toArray();
|
|
50
|
+
this._items.clear();
|
|
51
|
+
return leftovers;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Place an item on the retry queue. It's important that it's the
|
|
55
|
+
* same exact item that was already on the queue, if it's being retried
|
|
56
|
+
* more than once.
|
|
57
|
+
*
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
retryLater(item, callback) {
|
|
61
|
+
const retried = item;
|
|
62
|
+
const retryInfo = retried.retryInfo;
|
|
63
|
+
if (!retryInfo) {
|
|
64
|
+
// This item's first time through.
|
|
65
|
+
retried.retryInfo = {
|
|
66
|
+
firstRetry: Date.now(),
|
|
67
|
+
nextRetry: Date.now() + this.randomizeDelta(this._backoffMs),
|
|
68
|
+
multiplier: 1,
|
|
69
|
+
callback,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Not the first time - handle backoff.
|
|
74
|
+
const nextMultiplier = retryInfo.multiplier * 2;
|
|
75
|
+
let delta = this.randomizeDelta(nextMultiplier * this._backoffMs);
|
|
76
|
+
if (delta > this._maxBackoffMs) {
|
|
77
|
+
delta = this.randomizeDelta(this._maxBackoffMs);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
retryInfo.multiplier = nextMultiplier;
|
|
81
|
+
}
|
|
82
|
+
retryInfo.nextRetry = Date.now() + delta;
|
|
83
|
+
}
|
|
84
|
+
// Re-sort it into the heap with the correct position.
|
|
85
|
+
// It's my assumption here that any item that is being retried is
|
|
86
|
+
// very likely near or at the top.
|
|
87
|
+
this._items.remove(retried);
|
|
88
|
+
this._items.push(retried);
|
|
89
|
+
// Schedule the next retry.
|
|
90
|
+
this.scheduleRetry();
|
|
91
|
+
}
|
|
92
|
+
// Takes a time delta and adds fuzz.
|
|
93
|
+
randomizeDelta(durationMs) {
|
|
94
|
+
// The fuzz distance should never exceed one second, but in the
|
|
95
|
+
// case of smaller things, don't end up with a negative delta.
|
|
96
|
+
const magnitude = durationMs < 1000 ? durationMs : 1000;
|
|
97
|
+
const offset = Math.random() * magnitude - magnitude / 2.0;
|
|
98
|
+
return durationMs + offset;
|
|
99
|
+
}
|
|
100
|
+
// Looks through the queue to see if there's anything to handle.
|
|
101
|
+
doRetries() {
|
|
102
|
+
const now = Date.now();
|
|
103
|
+
while (!this._items.isEmpty()) {
|
|
104
|
+
const next = this._items.peek();
|
|
105
|
+
// Within 10msec is close enough.
|
|
106
|
+
if (next.retryInfo.nextRetry - now < 10) {
|
|
107
|
+
this._items.pop();
|
|
108
|
+
next.retryInfo.callback(next, temporal_1.Duration.from({ millis: now - next.retryInfo.firstRetry }));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Is there stuff to retry still?
|
|
115
|
+
if (!this._items.isEmpty()) {
|
|
116
|
+
this.scheduleRetry();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// If there are items to retry, schedule the next timer event.
|
|
120
|
+
scheduleRetry() {
|
|
121
|
+
// What's next?
|
|
122
|
+
const next = this._items.peek();
|
|
123
|
+
if (next) {
|
|
124
|
+
let delta = next.retryInfo.nextRetry - Date.now();
|
|
125
|
+
if (delta < 0) {
|
|
126
|
+
delta = 0;
|
|
127
|
+
}
|
|
128
|
+
if (this._timer) {
|
|
129
|
+
clearTimeout(this._timer);
|
|
130
|
+
}
|
|
131
|
+
this._timer = setTimeout(() => {
|
|
132
|
+
this.doRetries();
|
|
133
|
+
}, delta);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.ExponentialRetry = ExponentialRetry;
|
|
138
|
+
//# sourceMappingURL=exponential-retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exponential-retry.js","sourceRoot":"","sources":["../../src/exponential-retry.ts"],"names":[],"mappings":"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"}
|
package/build/src/index.d.ts
CHANGED
|
@@ -92,7 +92,7 @@ export { PageOptions, GetSnapshotsCallback, GetSnapshotsResponse, GetSubscriptio
|
|
|
92
92
|
export { CreateSnapshotCallback, CreateSnapshotResponse, SeekCallback, SeekResponse, Snapshot, } from './snapshot';
|
|
93
93
|
export { Message, SubscriberOptions } from './subscriber';
|
|
94
94
|
export { Schema, CreateSchemaResponse, ISchema, SchemaType, SchemaTypes, ICreateSchemaRequest, SchemaEncoding, SchemaView, SchemaViews, Encodings, SchemaMessageMetadata, } from './schema';
|
|
95
|
-
export { PushConfig, SubscriptionMetadata, SubscriptionOptions, SubscriptionCloseCallback, CreateSubscriptionOptions, CreateSubscriptionCallback, CreateSubscriptionResponse, GetSubscriptionOptions, GetSubscriptionCallback, GetSubscriptionResponse, GetSubscriptionMetadataCallback, GetSubscriptionMetadataResponse, SetSubscriptionMetadataCallback, SetSubscriptionMetadataResponse, Subscription, } from './subscription';
|
|
95
|
+
export { PushConfig, SubscriptionMetadata, SubscriptionOptions, SubscriptionCloseCallback, CreateSubscriptionOptions, CreateSubscriptionCallback, CreateSubscriptionResponse, GetSubscriptionOptions, GetSubscriptionCallback, GetSubscriptionResponse, GetSubscriptionMetadataCallback, GetSubscriptionMetadataResponse, SetSubscriptionMetadataCallback, SetSubscriptionMetadataResponse, Subscription, AckError, AckResponse, AckResponses, } from './subscription';
|
|
96
96
|
export { CreateTopicCallback, CreateTopicResponse, GetTopicCallback, GetTopicResponse, GetTopicOptions, GetTopicMetadataCallback, GetTopicMetadataResponse, GetTopicSubscriptionsCallback, GetTopicSubscriptionsResponse, SetTopicMetadataCallback, SetTopicMetadataResponse, Topic, TopicMetadata, } from './topic';
|
|
97
97
|
export { Duration, TotalOfUnit, DurationLike } from './temporal';
|
|
98
98
|
import * as protos from '../protos/protos';
|
package/build/src/index.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.protos = exports.Duration = exports.Topic = exports.Subscription = exports.Encodings = exports.SchemaViews = exports.SchemaTypes = exports.Schema = exports.Message = exports.Snapshot = exports.PubSub = exports.PublishError = exports.IAM = exports.v1 = void 0;
|
|
18
|
+
exports.protos = exports.Duration = exports.Topic = exports.AckResponses = exports.AckError = exports.Subscription = exports.Encodings = exports.SchemaViews = exports.SchemaTypes = exports.Schema = exports.Message = exports.Snapshot = exports.PubSub = exports.PublishError = exports.IAM = exports.v1 = void 0;
|
|
19
19
|
/**
|
|
20
20
|
* @namespace google.pubsub.v1
|
|
21
21
|
*/
|
|
@@ -102,6 +102,8 @@ Object.defineProperty(exports, "SchemaViews", { enumerable: true, get: function
|
|
|
102
102
|
Object.defineProperty(exports, "Encodings", { enumerable: true, get: function () { return schema_1.Encodings; } });
|
|
103
103
|
var subscription_1 = require("./subscription");
|
|
104
104
|
Object.defineProperty(exports, "Subscription", { enumerable: true, get: function () { return subscription_1.Subscription; } });
|
|
105
|
+
Object.defineProperty(exports, "AckError", { enumerable: true, get: function () { return subscription_1.AckError; } });
|
|
106
|
+
Object.defineProperty(exports, "AckResponses", { enumerable: true, get: function () { return subscription_1.AckResponses; } });
|
|
105
107
|
var topic_1 = require("./topic");
|
|
106
108
|
Object.defineProperty(exports, "Topic", { enumerable: true, get: function () { return topic_1.Topic; } });
|
|
107
109
|
var temporal_1 = require("./temporal");
|
package/build/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH;;GAEG;AACH;;GAEG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;GAWG;AACH,2BAA2B;AACnB,gBAAE;AAEV,6BAUe;AADb,0FAAA,GAAG,OAAA;AAIL,2DAAuD;AAA/C,6GAAA,YAAY,OAAA;AAEpB,mCAckB;AAFhB,gGAAA,MAAM,OAAA;AAGR,uCAMoB;AADlB,oGAAA,QAAQ,OAAA;AAEV,2CAAwD;AAAhD,qGAAA,OAAO,OAAA;AACf,mCAYkB;AAXhB,gGAAA,MAAM,OAAA;AAIN,qGAAA,WAAW,OAAA;AAIX,qGAAA,WAAW,OAAA;AACX,mGAAA,SAAS,OAAA;AAGX,+
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH;;GAEG;AACH;;GAEG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;GAWG;AACH,2BAA2B;AACnB,gBAAE;AAEV,6BAUe;AADb,0FAAA,GAAG,OAAA;AAIL,2DAAuD;AAA/C,6GAAA,YAAY,OAAA;AAEpB,mCAckB;AAFhB,gGAAA,MAAM,OAAA;AAGR,uCAMoB;AADlB,oGAAA,QAAQ,OAAA;AAEV,2CAAwD;AAAhD,qGAAA,OAAO,OAAA;AACf,mCAYkB;AAXhB,gGAAA,MAAM,OAAA;AAIN,qGAAA,WAAW,OAAA;AAIX,qGAAA,WAAW,OAAA;AACX,mGAAA,SAAS,OAAA;AAGX,+CAmBwB;AAJtB,4GAAA,YAAY,OAAA;AACZ,wGAAA,QAAQ,OAAA;AAER,4GAAA,YAAY,OAAA;AAEd,iCAciB;AAFf,8FAAA,KAAK,OAAA;AAGP,uCAA+D;AAAvD,oGAAA,QAAQ,OAAA;AAEhB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE;IAC1B,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC;IACxC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACxB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;CAC/C;AACD,2CAA2C;AACnC,wBAAM"}
|
|
@@ -14,10 +14,23 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
/// <reference types="node" />
|
|
17
|
-
import { CallOptions, grpc } from 'google-gax';
|
|
17
|
+
import { CallOptions, GoogleError, grpc } from 'google-gax';
|
|
18
18
|
import defer = require('p-defer');
|
|
19
|
-
import {
|
|
20
|
-
|
|
19
|
+
import { ExponentialRetry } from './exponential-retry';
|
|
20
|
+
import { AckResponse, Message, Subscriber } from './subscriber';
|
|
21
|
+
/**
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
export interface QueuedMessage {
|
|
25
|
+
ackId: string;
|
|
26
|
+
deadline?: number;
|
|
27
|
+
responsePromise?: defer.DeferredPromise<void>;
|
|
28
|
+
retryCount: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
export declare type QueuedMessages = Array<QueuedMessage>;
|
|
21
34
|
export interface BatchOptions {
|
|
22
35
|
callOptions?: CallOptions;
|
|
23
36
|
maxMessages?: number;
|
|
@@ -26,17 +39,19 @@ export interface BatchOptions {
|
|
|
26
39
|
/**
|
|
27
40
|
* Error class used to signal a batch failure.
|
|
28
41
|
*
|
|
42
|
+
* Now that we have exactly-once delivery subscriptions, we'll only
|
|
43
|
+
* throw one of these if there was an unknown error.
|
|
44
|
+
*
|
|
29
45
|
* @class
|
|
30
46
|
*
|
|
31
47
|
* @param {string} message The error message.
|
|
32
|
-
* @param {
|
|
48
|
+
* @param {GoogleError} err The grpc error.
|
|
33
49
|
*/
|
|
34
|
-
export declare class BatchError extends Error
|
|
50
|
+
export declare class BatchError extends Error {
|
|
35
51
|
ackIds: string[];
|
|
36
52
|
code: grpc.status;
|
|
37
53
|
details: string;
|
|
38
|
-
|
|
39
|
-
constructor(err: grpc.ServiceError, ackIds: string[], rpc: string);
|
|
54
|
+
constructor(err: GoogleError, ackIds: string[], rpc: string);
|
|
40
55
|
}
|
|
41
56
|
/**
|
|
42
57
|
* @typedef {object} BatchOptions
|
|
@@ -60,14 +75,28 @@ export declare class BatchError extends Error implements grpc.ServiceError {
|
|
|
60
75
|
export declare abstract class MessageQueue {
|
|
61
76
|
numPendingRequests: number;
|
|
62
77
|
numInFlightRequests: number;
|
|
78
|
+
numInRetryRequests: number;
|
|
63
79
|
protected _onFlush?: defer.DeferredPromise<void>;
|
|
64
80
|
protected _onDrain?: defer.DeferredPromise<void>;
|
|
65
81
|
protected _options: BatchOptions;
|
|
66
82
|
protected _requests: QueuedMessages;
|
|
67
83
|
protected _subscriber: Subscriber;
|
|
68
84
|
protected _timer?: NodeJS.Timer;
|
|
69
|
-
protected
|
|
85
|
+
protected _retrier: ExponentialRetry<QueuedMessage>;
|
|
86
|
+
protected _closed: boolean;
|
|
87
|
+
protected abstract _sendBatch(batch: QueuedMessages): Promise<QueuedMessages>;
|
|
70
88
|
constructor(sub: Subscriber, options?: BatchOptions);
|
|
89
|
+
/**
|
|
90
|
+
* Shuts down this message queue gracefully. Any acks/modAcks pending in
|
|
91
|
+
* the queue or waiting for retry will be removed. If exactly-once delivery
|
|
92
|
+
* is enabled on the subscription, we'll send permanent failures to
|
|
93
|
+
* anyone waiting on completions; otherwise we'll send successes.
|
|
94
|
+
*
|
|
95
|
+
* If a flush is desired first, do it before calling close().
|
|
96
|
+
*
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
close(): void;
|
|
71
100
|
/**
|
|
72
101
|
* Gets the default buffer time in ms.
|
|
73
102
|
*
|
|
@@ -82,7 +111,20 @@ export declare abstract class MessageQueue {
|
|
|
82
111
|
* @param {number} [deadline] The deadline.
|
|
83
112
|
* @private
|
|
84
113
|
*/
|
|
85
|
-
add({ ackId }: Message, deadline?: number): void
|
|
114
|
+
add({ ackId }: Message, deadline?: number): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Retry handler for acks/modacks that have transient failures. Unless
|
|
117
|
+
* it's passed the final deadline, we will just re-queue it for sending.
|
|
118
|
+
*
|
|
119
|
+
* @private
|
|
120
|
+
*/
|
|
121
|
+
private handleRetry;
|
|
122
|
+
/**
|
|
123
|
+
* This hook lets a subclass tell the retry handler to go ahead and fail early.
|
|
124
|
+
*
|
|
125
|
+
* @private
|
|
126
|
+
*/
|
|
127
|
+
protected shouldFailEarly(message: QueuedMessage): boolean;
|
|
86
128
|
/**
|
|
87
129
|
* Sends a batch of messages.
|
|
88
130
|
* @private
|
|
@@ -106,6 +148,37 @@ export declare abstract class MessageQueue {
|
|
|
106
148
|
* @private
|
|
107
149
|
*/
|
|
108
150
|
setOptions(options: BatchOptions): void;
|
|
151
|
+
/**
|
|
152
|
+
* Succeed a whole batch of Acks/Modacks for an OK RPC response.
|
|
153
|
+
*
|
|
154
|
+
* @private
|
|
155
|
+
*/
|
|
156
|
+
handleAckSuccesses(batch: QueuedMessages): void;
|
|
157
|
+
/**
|
|
158
|
+
* If we get an RPC failure of any kind, this will take care of deciding
|
|
159
|
+
* what to do for each related ack/modAck. Successful ones will have their
|
|
160
|
+
* Promises resolved, permanent errors will have their Promises rejected,
|
|
161
|
+
* and transients will be returned for retry.
|
|
162
|
+
*
|
|
163
|
+
* Note that this is only used for subscriptions with exactly-once
|
|
164
|
+
* delivery enabled, so _sendBatch() in the classes below take care of
|
|
165
|
+
* resolving errors to success; they don't make it here.
|
|
166
|
+
*
|
|
167
|
+
* @private
|
|
168
|
+
*/
|
|
169
|
+
handleAckFailures(operation: string, batch: QueuedMessages, rpcError: GoogleError): {
|
|
170
|
+
toError: Map<AckResponse, QueuedMessages>;
|
|
171
|
+
toRetry: QueuedMessages;
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Since we handle our own retries for ack/modAck calls when exactly-once
|
|
175
|
+
* delivery is enabled on a subscription, we conditionally need to disable
|
|
176
|
+
* the gax retries. This returns an appropriate CallOptions for the
|
|
177
|
+
* subclasses to pass down.
|
|
178
|
+
*
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
protected getCallOptions(): CallOptions | undefined;
|
|
109
182
|
}
|
|
110
183
|
/**
|
|
111
184
|
* Queues up Acknowledge (ack) requests.
|
|
@@ -122,7 +195,7 @@ export declare class AckQueue extends MessageQueue {
|
|
|
122
195
|
* @param {Array.<Array.<string|number>>} batch Array of ackIds and deadlines.
|
|
123
196
|
* @return {Promise}
|
|
124
197
|
*/
|
|
125
|
-
protected _sendBatch(batch: QueuedMessages): Promise<
|
|
198
|
+
protected _sendBatch(batch: QueuedMessages): Promise<QueuedMessages>;
|
|
126
199
|
}
|
|
127
200
|
/**
|
|
128
201
|
* Queues up ModifyAckDeadline requests and sends them out in batches.
|
|
@@ -140,6 +213,6 @@ export declare class ModAckQueue extends MessageQueue {
|
|
|
140
213
|
* @param {Array.<Array.<string|number>>} batch Array of ackIds and deadlines.
|
|
141
214
|
* @return {Promise}
|
|
142
215
|
*/
|
|
143
|
-
protected _sendBatch(batch: QueuedMessages): Promise<
|
|
216
|
+
protected _sendBatch(batch: QueuedMessages): Promise<QueuedMessages>;
|
|
217
|
+
protected shouldFailEarly(message: QueuedMessage): boolean;
|
|
144
218
|
}
|
|
145
|
-
export {};
|