@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.
Files changed (44) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +2 -0
  3. package/build/protos/protos.d.ts +689 -2
  4. package/build/protos/protos.js +3162 -1244
  5. package/build/protos/protos.json +17 -0
  6. package/build/src/ack-metadata.d.ts +29 -0
  7. package/build/src/ack-metadata.js +93 -0
  8. package/build/src/ack-metadata.js.map +1 -0
  9. package/build/src/exponential-retry.d.ts +66 -0
  10. package/build/src/exponential-retry.js +138 -0
  11. package/build/src/exponential-retry.js.map +1 -0
  12. package/build/src/index.d.ts +1 -1
  13. package/build/src/index.js +3 -1
  14. package/build/src/index.js.map +1 -1
  15. package/build/src/message-queues.d.ts +85 -12
  16. package/build/src/message-queues.js +279 -19
  17. package/build/src/message-queues.js.map +1 -1
  18. package/build/src/message-stream.d.ts +7 -0
  19. package/build/src/message-stream.js +14 -0
  20. package/build/src/message-stream.js.map +1 -1
  21. package/build/src/publisher/index.js +12 -3
  22. package/build/src/publisher/index.js.map +1 -1
  23. package/build/src/publisher/message-queues.d.ts +2 -0
  24. package/build/src/publisher/message-queues.js +16 -1
  25. package/build/src/publisher/message-queues.js.map +1 -1
  26. package/build/src/subscriber.d.ts +86 -6
  27. package/build/src/subscriber.js +168 -26
  28. package/build/src/subscriber.js.map +1 -1
  29. package/build/src/subscription.d.ts +1 -1
  30. package/build/src/subscription.js +4 -1
  31. package/build/src/subscription.js.map +1 -1
  32. package/build/src/util.d.ts +6 -0
  33. package/build/src/util.js +13 -1
  34. package/build/src/util.js.map +1 -1
  35. package/build/src/v1/publisher_client.d.ts +11 -4
  36. package/build/src/v1/publisher_client.js +62 -39
  37. package/build/src/v1/publisher_client.js.map +1 -1
  38. package/build/src/v1/schema_service_client.d.ts +11 -4
  39. package/build/src/v1/schema_service_client.js +40 -24
  40. package/build/src/v1/schema_service_client.js.map +1 -1
  41. package/build/src/v1/subscriber_client.d.ts +10 -3
  42. package/build/src/v1/subscriber_client.js +75 -48
  43. package/build/src/v1/subscriber_client.js.map +1 -1
  44. package/package.json +6 -5
@@ -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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"}
@@ -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';
@@ -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");
@@ -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,+CAgBwB;AADtB,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"}
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 { Message, Subscriber } from './subscriber';
20
- declare type QueuedMessages = Array<[string, number?]>;
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 {ServiceError} err The grpc service error.
48
+ * @param {GoogleError} err The grpc error.
33
49
  */
34
- export declare class BatchError extends Error implements grpc.ServiceError {
50
+ export declare class BatchError extends Error {
35
51
  ackIds: string[];
36
52
  code: grpc.status;
37
53
  details: string;
38
- metadata: grpc.Metadata;
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 abstract _sendBatch(batch: QueuedMessages): Promise<void>;
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<void>;
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<void>;
216
+ protected _sendBatch(batch: QueuedMessages): Promise<QueuedMessages>;
217
+ protected shouldFailEarly(message: QueuedMessage): boolean;
144
218
  }
145
- export {};