rocketmq-client-nodejs-bate 1.0.12

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 (209) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +186 -0
  3. package/dist/client/BaseClient.d.ts +95 -0
  4. package/dist/client/BaseClient.js +324 -0
  5. package/dist/client/ClientId.d.ts +24 -0
  6. package/dist/client/ClientId.js +33 -0
  7. package/dist/client/Logger.d.ts +25 -0
  8. package/dist/client/Logger.js +33 -0
  9. package/dist/client/RpcClient.d.ts +48 -0
  10. package/dist/client/RpcClient.js +219 -0
  11. package/dist/client/RpcClientManager.d.ts +42 -0
  12. package/dist/client/RpcClientManager.js +144 -0
  13. package/dist/client/SessionCredentials.d.ts +21 -0
  14. package/dist/client/SessionCredentials.js +19 -0
  15. package/dist/client/Settings.d.ts +31 -0
  16. package/dist/client/Settings.js +40 -0
  17. package/dist/client/TelemetrySession.d.ts +27 -0
  18. package/dist/client/TelemetrySession.js +110 -0
  19. package/dist/client/UserAgent.d.ts +25 -0
  20. package/dist/client/UserAgent.js +47 -0
  21. package/dist/client/index.d.ts +26 -0
  22. package/dist/client/index.js +43 -0
  23. package/dist/consumer/Assignment.d.ts +23 -0
  24. package/dist/consumer/Assignment.js +40 -0
  25. package/dist/consumer/Assignments.d.ts +24 -0
  26. package/dist/consumer/Assignments.js +47 -0
  27. package/dist/consumer/ConsumeResult.d.ts +20 -0
  28. package/dist/consumer/ConsumeResult.js +25 -0
  29. package/dist/consumer/ConsumeService.d.ts +28 -0
  30. package/dist/consumer/ConsumeService.js +49 -0
  31. package/dist/consumer/ConsumeTask.d.ts +24 -0
  32. package/dist/consumer/ConsumeTask.js +40 -0
  33. package/dist/consumer/Consumer.d.ts +38 -0
  34. package/dist/consumer/Consumer.js +111 -0
  35. package/dist/consumer/FifoConsumeService.d.ts +25 -0
  36. package/dist/consumer/FifoConsumeService.js +123 -0
  37. package/dist/consumer/FilterExpression.d.ts +25 -0
  38. package/dist/consumer/FilterExpression.js +40 -0
  39. package/dist/consumer/MessageListener.d.ts +21 -0
  40. package/dist/consumer/MessageListener.js +19 -0
  41. package/dist/consumer/ProcessQueue.d.ts +39 -0
  42. package/dist/consumer/ProcessQueue.js +286 -0
  43. package/dist/consumer/PushConsumer.d.ts +68 -0
  44. package/dist/consumer/PushConsumer.js +377 -0
  45. package/dist/consumer/PushSubscriptionSettings.d.ts +31 -0
  46. package/dist/consumer/PushSubscriptionSettings.js +97 -0
  47. package/dist/consumer/SimpleConsumer.d.ts +50 -0
  48. package/dist/consumer/SimpleConsumer.js +122 -0
  49. package/dist/consumer/SimpleSubscriptionSettings.d.ts +28 -0
  50. package/dist/consumer/SimpleSubscriptionSettings.js +57 -0
  51. package/dist/consumer/StandardConsumeService.d.ts +24 -0
  52. package/dist/consumer/StandardConsumeService.js +42 -0
  53. package/dist/consumer/SubscriptionLoadBalancer.d.ts +23 -0
  54. package/dist/consumer/SubscriptionLoadBalancer.js +46 -0
  55. package/dist/consumer/index.d.ts +32 -0
  56. package/dist/consumer/index.js +49 -0
  57. package/dist/exception/BadRequestException.d.ts +20 -0
  58. package/dist/exception/BadRequestException.js +28 -0
  59. package/dist/exception/ClientException.d.ts +20 -0
  60. package/dist/exception/ClientException.js +31 -0
  61. package/dist/exception/ForbiddenException.d.ts +20 -0
  62. package/dist/exception/ForbiddenException.js +28 -0
  63. package/dist/exception/InternalErrorException.d.ts +20 -0
  64. package/dist/exception/InternalErrorException.js +28 -0
  65. package/dist/exception/NotFoundException.d.ts +20 -0
  66. package/dist/exception/NotFoundException.js +28 -0
  67. package/dist/exception/PayloadTooLargeException.d.ts +20 -0
  68. package/dist/exception/PayloadTooLargeException.js +28 -0
  69. package/dist/exception/PaymentRequiredException.d.ts +20 -0
  70. package/dist/exception/PaymentRequiredException.js +28 -0
  71. package/dist/exception/ProxyTimeoutException.d.ts +20 -0
  72. package/dist/exception/ProxyTimeoutException.js +28 -0
  73. package/dist/exception/RequestHeaderFieldsTooLargeException.d.ts +20 -0
  74. package/dist/exception/RequestHeaderFieldsTooLargeException.js +28 -0
  75. package/dist/exception/StatusChecker.d.ts +20 -0
  76. package/dist/exception/StatusChecker.js +98 -0
  77. package/dist/exception/TooManyRequestsException.d.ts +20 -0
  78. package/dist/exception/TooManyRequestsException.js +28 -0
  79. package/dist/exception/UnauthorizedException.d.ts +20 -0
  80. package/dist/exception/UnauthorizedException.js +28 -0
  81. package/dist/exception/UnsupportedException.d.ts +20 -0
  82. package/dist/exception/UnsupportedException.js +28 -0
  83. package/dist/exception/index.d.ts +29 -0
  84. package/dist/exception/index.js +46 -0
  85. package/dist/index.d.ts +22 -0
  86. package/dist/index.js +39 -0
  87. package/dist/message/Message.d.ts +38 -0
  88. package/dist/message/Message.js +57 -0
  89. package/dist/message/MessageId.d.ts +59 -0
  90. package/dist/message/MessageId.js +123 -0
  91. package/dist/message/MessageView.d.ts +38 -0
  92. package/dist/message/MessageView.js +90 -0
  93. package/dist/message/PublishingMessage.d.ts +30 -0
  94. package/dist/message/PublishingMessage.js +100 -0
  95. package/dist/message/index.d.ts +20 -0
  96. package/dist/message/index.js +37 -0
  97. package/dist/producer/Producer.d.ts +55 -0
  98. package/dist/producer/Producer.js +318 -0
  99. package/dist/producer/PublishingLoadBalancer.d.ts +24 -0
  100. package/dist/producer/PublishingLoadBalancer.js +82 -0
  101. package/dist/producer/PublishingSettings.d.ts +28 -0
  102. package/dist/producer/PublishingSettings.js +70 -0
  103. package/dist/producer/RecallReceipt.d.ts +25 -0
  104. package/dist/producer/RecallReceipt.js +34 -0
  105. package/dist/producer/SendReceipt.d.ts +29 -0
  106. package/dist/producer/SendReceipt.js +60 -0
  107. package/dist/producer/Transaction.d.ts +28 -0
  108. package/dist/producer/Transaction.js +70 -0
  109. package/dist/producer/TransactionChecker.d.ts +21 -0
  110. package/dist/producer/TransactionChecker.js +19 -0
  111. package/dist/producer/index.d.ts +22 -0
  112. package/dist/producer/index.js +40 -0
  113. package/dist/retry/ExponentialBackoffRetryPolicy.d.ts +27 -0
  114. package/dist/retry/ExponentialBackoffRetryPolicy.js +64 -0
  115. package/dist/retry/RetryPolicy.d.ts +46 -0
  116. package/dist/retry/RetryPolicy.js +19 -0
  117. package/dist/retry/index.d.ts +18 -0
  118. package/dist/retry/index.js +35 -0
  119. package/dist/route/Broker.d.ts +25 -0
  120. package/dist/route/Broker.js +40 -0
  121. package/dist/route/Endpoints.d.ts +30 -0
  122. package/dist/route/Endpoints.js +71 -0
  123. package/dist/route/MessageQueue.d.ts +27 -0
  124. package/dist/route/MessageQueue.js +47 -0
  125. package/dist/route/TopicRouteData.d.ts +24 -0
  126. package/dist/route/TopicRouteData.js +37 -0
  127. package/dist/route/index.d.ts +20 -0
  128. package/dist/route/index.js +37 -0
  129. package/dist/util/index.d.ts +35 -0
  130. package/dist/util/index.js +88 -0
  131. package/package.json +62 -0
  132. package/proto/apache/rocketmq/v2/admin.proto +43 -0
  133. package/proto/apache/rocketmq/v2/admin_grpc_pb.d.ts +41 -0
  134. package/proto/apache/rocketmq/v2/admin_grpc_pb.js +60 -0
  135. package/proto/apache/rocketmq/v2/admin_pb.d.ts +56 -0
  136. package/proto/apache/rocketmq/v2/admin_pb.js +340 -0
  137. package/proto/apache/rocketmq/v2/definition.proto +570 -0
  138. package/proto/apache/rocketmq/v2/definition_grpc_pb.js +1 -0
  139. package/proto/apache/rocketmq/v2/definition_pb.d.ts +885 -0
  140. package/proto/apache/rocketmq/v2/definition_pb.js +6141 -0
  141. package/proto/apache/rocketmq/v2/service.proto +443 -0
  142. package/proto/apache/rocketmq/v2/service_grpc_pb.d.ts +294 -0
  143. package/proto/apache/rocketmq/v2/service_grpc_pb.js +637 -0
  144. package/proto/apache/rocketmq/v2/service_pb.d.ts +1249 -0
  145. package/proto/apache/rocketmq/v2/service_pb.js +9723 -0
  146. package/src/client/BaseClient.ts +404 -0
  147. package/src/client/ClientId.ts +31 -0
  148. package/src/client/Logger.ts +36 -0
  149. package/src/client/RpcClient.ts +258 -0
  150. package/src/client/RpcClientManager.ts +180 -0
  151. package/src/client/SessionCredentials.ts +22 -0
  152. package/src/client/Settings.ts +46 -0
  153. package/src/client/TelemetrySession.ts +130 -0
  154. package/src/client/UserAgent.ts +45 -0
  155. package/src/client/index.ts +27 -0
  156. package/src/consumer/Assignment.ts +39 -0
  157. package/src/consumer/Assignments.ts +46 -0
  158. package/src/consumer/ConsumeResult.ts +21 -0
  159. package/src/consumer/ConsumeService.ts +54 -0
  160. package/src/consumer/ConsumeTask.ts +40 -0
  161. package/src/consumer/Consumer.ts +129 -0
  162. package/src/consumer/FifoConsumeService.ts +136 -0
  163. package/src/consumer/FilterExpression.ts +42 -0
  164. package/src/consumer/MessageListener.ts +23 -0
  165. package/src/consumer/ProcessQueue.ts +326 -0
  166. package/src/consumer/PushConsumer.ts +473 -0
  167. package/src/consumer/PushSubscriptionSettings.ts +123 -0
  168. package/src/consumer/SimpleConsumer.ts +153 -0
  169. package/src/consumer/SimpleSubscriptionSettings.ts +64 -0
  170. package/src/consumer/StandardConsumeService.ts +44 -0
  171. package/src/consumer/SubscriptionLoadBalancer.ts +47 -0
  172. package/src/consumer/index.ts +33 -0
  173. package/src/exception/BadRequestException.ts +25 -0
  174. package/src/exception/ClientException.ts +29 -0
  175. package/src/exception/ForbiddenException.ts +25 -0
  176. package/src/exception/InternalErrorException.ts +25 -0
  177. package/src/exception/NotFoundException.ts +25 -0
  178. package/src/exception/PayloadTooLargeException.ts +25 -0
  179. package/src/exception/PaymentRequiredException.ts +25 -0
  180. package/src/exception/ProxyTimeoutException.ts +25 -0
  181. package/src/exception/RequestHeaderFieldsTooLargeException.ts +25 -0
  182. package/src/exception/StatusChecker.ts +94 -0
  183. package/src/exception/TooManyRequestsException.ts +25 -0
  184. package/src/exception/UnauthorizedException.ts +25 -0
  185. package/src/exception/UnsupportedException.ts +25 -0
  186. package/src/exception/index.ts +30 -0
  187. package/src/index.ts +23 -0
  188. package/src/message/Message.ts +67 -0
  189. package/src/message/MessageId.ts +123 -0
  190. package/src/message/MessageView.ts +94 -0
  191. package/src/message/PublishingMessage.ts +104 -0
  192. package/src/message/index.ts +21 -0
  193. package/src/producer/Producer.ts +388 -0
  194. package/src/producer/PublishingLoadBalancer.ts +85 -0
  195. package/src/producer/PublishingSettings.ts +78 -0
  196. package/src/producer/RecallReceipt.ts +32 -0
  197. package/src/producer/SendReceipt.ts +63 -0
  198. package/src/producer/Transaction.ts +86 -0
  199. package/src/producer/TransactionChecker.ts +23 -0
  200. package/src/producer/index.ts +24 -0
  201. package/src/retry/ExponentialBackoffRetryPolicy.ts +76 -0
  202. package/src/retry/RetryPolicy.ts +51 -0
  203. package/src/retry/index.ts +19 -0
  204. package/src/route/Broker.ts +39 -0
  205. package/src/route/Endpoints.ts +70 -0
  206. package/src/route/MessageQueue.ts +49 -0
  207. package/src/route/TopicRouteData.ts +38 -0
  208. package/src/route/index.ts +21 -0
  209. package/src/util/index.ts +83 -0
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ export * from './BaseClient';
19
+ export * from './ClientId';
20
+ export * from './Logger';
21
+ export * from './UserAgent';
22
+ export * from './RpcClient';
23
+ export * from './RpcClientManager';
24
+ export * from './SessionCredentials';
25
+ export * from './Settings';
26
+ export * from './TelemetrySession';
27
+ export * from './UserAgent';
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { MessageQueue } from '../route';
19
+
20
+ export class Assignment {
21
+ readonly messageQueue: MessageQueue;
22
+
23
+ constructor(messageQueue: MessageQueue) {
24
+ this.messageQueue = messageQueue;
25
+ }
26
+
27
+ equals(other: Assignment): boolean {
28
+ if (this === other) return true;
29
+ if (!other) return false;
30
+ return this.messageQueue === other.messageQueue ||
31
+ (this.messageQueue.queueId === other.messageQueue.queueId &&
32
+ this.messageQueue.topic.name === other.messageQueue.topic.name &&
33
+ this.messageQueue.broker.name === other.messageQueue.broker.name);
34
+ }
35
+
36
+ toString(): string {
37
+ return `Assignment{messageQueue=${JSON.stringify(this.messageQueue)}}`;
38
+ }
39
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { Assignment } from './Assignment';
19
+
20
+ export class Assignments {
21
+ readonly #assignmentList: Assignment[];
22
+
23
+ constructor(assignmentList: Assignment[]) {
24
+ this.#assignmentList = assignmentList;
25
+ }
26
+
27
+ getAssignmentList(): Assignment[] {
28
+ return this.#assignmentList;
29
+ }
30
+
31
+ equals(other?: Assignments): boolean {
32
+ if (this === other) return true;
33
+ if (!other) return false;
34
+ if (this.#assignmentList.length !== other.#assignmentList.length) return false;
35
+ for (let i = 0; i < this.#assignmentList.length; i++) {
36
+ if (!this.#assignmentList[i].equals(other.#assignmentList[i])) {
37
+ return false;
38
+ }
39
+ }
40
+ return true;
41
+ }
42
+
43
+ toString(): string {
44
+ return `Assignments{assignmentList=[${this.#assignmentList.map(a => a.toString()).join(', ')}]}`;
45
+ }
46
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ export enum ConsumeResult {
19
+ SUCCESS = 'SUCCESS',
20
+ FAILURE = 'FAILURE',
21
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { MessageView } from '../message';
19
+ import { ConsumeResult } from './ConsumeResult';
20
+ import { ConsumeTask } from './ConsumeTask';
21
+ import { MessageListener } from './MessageListener';
22
+ import type { ProcessQueue } from './ProcessQueue';
23
+
24
+ export abstract class ConsumeService {
25
+ protected readonly clientId: string;
26
+ readonly #messageListener: MessageListener;
27
+ #aborted = false;
28
+
29
+ constructor(clientId: string, messageListener: MessageListener) {
30
+ this.clientId = clientId;
31
+ this.#messageListener = messageListener;
32
+ }
33
+
34
+ abstract consume(pq: ProcessQueue, messageViews: MessageView[]): void;
35
+
36
+ async consumeMessage(messageView: MessageView, delay = 0): Promise<ConsumeResult> {
37
+ if (this.#aborted) {
38
+ return ConsumeResult.FAILURE;
39
+ }
40
+ const task = new ConsumeTask(this.clientId, this.#messageListener, messageView);
41
+ if (delay <= 0) {
42
+ return task.call();
43
+ }
44
+ await new Promise<void>(resolve => setTimeout(resolve, delay));
45
+ if (this.#aborted) {
46
+ return ConsumeResult.FAILURE;
47
+ }
48
+ return task.call();
49
+ }
50
+
51
+ abort() {
52
+ this.#aborted = true;
53
+ }
54
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { MessageView } from '../message';
19
+ import { ConsumeResult } from './ConsumeResult';
20
+ import { MessageListener } from './MessageListener';
21
+
22
+ export class ConsumeTask {
23
+ readonly #messageListener: MessageListener;
24
+ readonly #messageView: MessageView;
25
+
26
+ constructor(_clientId: string, messageListener: MessageListener, messageView: MessageView) {
27
+ this.#messageListener = messageListener;
28
+ this.#messageView = messageView;
29
+ }
30
+
31
+ async call(): Promise<ConsumeResult> {
32
+ try {
33
+ const result = await this.#messageListener.consume(this.#messageView);
34
+ return result;
35
+ } catch (e) {
36
+ // Message listener raised an exception while consuming messages
37
+ return ConsumeResult.FAILURE;
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { Message, Status } from '../../proto/apache/rocketmq/v2/definition_pb';
19
+ import {
20
+ AckMessageRequest,
21
+ ChangeInvisibleDurationRequest,
22
+ ReceiveMessageRequest, ReceiveMessageResponse,
23
+ } from '../../proto/apache/rocketmq/v2/service_pb';
24
+ import { MessageView } from '../message';
25
+ import { MessageQueue } from '../route';
26
+ import { StatusChecker } from '../exception';
27
+ import { BaseClient, BaseClientOptions } from '../client';
28
+ import { createDuration, createResource } from '../util';
29
+ import { FilterExpression } from './FilterExpression';
30
+
31
+ export interface ConsumerOptions extends BaseClientOptions {
32
+ consumerGroup: string;
33
+ }
34
+
35
+ export abstract class Consumer extends BaseClient {
36
+ protected readonly consumerGroup: string;
37
+
38
+ constructor(options: ConsumerOptions) {
39
+ super(options);
40
+ this.consumerGroup = options.consumerGroup;
41
+ }
42
+
43
+ protected wrapReceiveMessageRequest(batchSize: number, mq: MessageQueue,
44
+ filterExpression: FilterExpression, invisibleDuration: number, longPollingTimeout: number) {
45
+ return new ReceiveMessageRequest()
46
+ .setGroup(createResource(this.consumerGroup))
47
+ .setMessageQueue(mq.toProtobuf())
48
+ .setFilterExpression(filterExpression.toProtobuf())
49
+ .setLongPollingTimeout(createDuration(longPollingTimeout))
50
+ .setBatchSize(batchSize)
51
+ .setAutoRenew(false)
52
+ .setInvisibleDuration(createDuration(invisibleDuration));
53
+ }
54
+
55
+ protected async receiveMessage(request: ReceiveMessageRequest, mq: MessageQueue, awaitDuration: number) {
56
+ const endpoints = mq.broker.endpoints;
57
+ const timeout = this.requestTimeout + awaitDuration;
58
+ let status: Status.AsObject | undefined;
59
+ const responses = await this.rpcClientManager.receiveMessage(endpoints, request, timeout);
60
+ const messageList: Message[] = [];
61
+ let transportDeliveryTimestamp: Date | undefined;
62
+ for (const response of responses) {
63
+ switch (response.getContentCase()) {
64
+ case ReceiveMessageResponse.ContentCase.STATUS:
65
+ status = response.getStatus()?.toObject();
66
+ break;
67
+ case ReceiveMessageResponse.ContentCase.MESSAGE:
68
+ messageList.push(response.getMessage()!);
69
+ break;
70
+ case ReceiveMessageResponse.ContentCase.DELIVERY_TIMESTAMP:
71
+ transportDeliveryTimestamp = response.getDeliveryTimestamp()?.toDate();
72
+ break;
73
+ default:
74
+ // this.logger.warn("[Bug] Not recognized content for receive message response, mq={}, " +
75
+ // "clientId={}, response={}", mq, clientId, response);
76
+ }
77
+ }
78
+ StatusChecker.check(status);
79
+ const messages = messageList.map(message => new MessageView(message, mq, transportDeliveryTimestamp));
80
+ return messages;
81
+ }
82
+
83
+ protected async ackMessage(messageView: MessageView) {
84
+ const endpoints = messageView.endpoints;
85
+ const request = new AckMessageRequest()
86
+ .setGroup(createResource(this.consumerGroup))
87
+ .setTopic(createResource(messageView.topic));
88
+ request.addEntries()
89
+ .setMessageId(messageView.messageId)
90
+ .setReceiptHandle(messageView.receiptHandle);
91
+ const res = await this.rpcClientManager.ackMessage(endpoints, request, this.requestTimeout);
92
+ // FIXME: handle fail ack
93
+ const response = res.toObject();
94
+ StatusChecker.check(response.status);
95
+ return response.entriesList;
96
+ }
97
+
98
+ protected async invisibleDuration(messageView: MessageView, invisibleDuration: number) {
99
+ const request = new ChangeInvisibleDurationRequest()
100
+ .setGroup(createResource(this.consumerGroup))
101
+ .setTopic(createResource(messageView.topic))
102
+ .setReceiptHandle(messageView.receiptHandle)
103
+ .setInvisibleDuration(createDuration(invisibleDuration))
104
+ .setMessageId(messageView.messageId);
105
+
106
+ const res = await this.rpcClientManager.changeInvisibleDuration(messageView.endpoints, request, this.requestTimeout);
107
+ const response = res.toObject();
108
+ StatusChecker.check(response.status);
109
+ return response.receiptHandle;
110
+ }
111
+
112
+ /**
113
+ * Expose public methods for ProcessQueue to access RPC operations
114
+ */
115
+ async ackMessageViaRpc(endpoints: any, request: AckMessageRequest, timeout: number) {
116
+ const res = await this.rpcClientManager.ackMessage(endpoints, request, timeout);
117
+ return res;
118
+ }
119
+
120
+ async changeInvisibleDurationViaRpc(endpoints: any, request: ChangeInvisibleDurationRequest, timeout: number) {
121
+ const res = await this.rpcClientManager.changeInvisibleDuration(endpoints, request, timeout);
122
+ return res;
123
+ }
124
+
125
+ async forwardMessageToDeadLetterQueueViaRpc(endpoints: any, request: any, timeout: number) {
126
+ const res = await this.rpcClientManager.forwardMessageToDeadLetterQueue(endpoints, request, timeout);
127
+ return res;
128
+ }
129
+ }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { MessageView } from '../message';
19
+ import { ConsumeService } from './ConsumeService';
20
+ import { MessageListener } from './MessageListener';
21
+ import type { ProcessQueue } from './ProcessQueue';
22
+
23
+ export class FifoConsumeService extends ConsumeService {
24
+ readonly #enableAccelerator: boolean;
25
+ readonly #groupProcessing = new Map<string /* messageGroup */, Promise<void>>();
26
+
27
+ constructor(clientId: string, messageListener: MessageListener, enableAccelerator?: boolean) {
28
+ super(clientId, messageListener);
29
+ this.#enableAccelerator = enableAccelerator ?? false;
30
+ }
31
+
32
+ consume(pq: ProcessQueue, messageViews: MessageView[]): void {
33
+ if (this.#enableAccelerator) {
34
+ this.#consumeWithAccelerator(pq, messageViews);
35
+ } else {
36
+ this.#consumeIteratively(pq, messageViews, 0);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * FIFO consume accelerator mode:
42
+ * - Messages with the same messageGroup are consumed sequentially
43
+ * - Messages with different messageGroups are consumed in parallel
44
+ * - Messages without messageGroup are consumed in parallel
45
+ */
46
+ #consumeWithAccelerator(pq: ProcessQueue, messageViews: MessageView[]): void {
47
+ // Group messages by messageGroup
48
+ const groupedMessages = new Map<string, MessageView[]>();
49
+ const ungroupedMessages: MessageView[] = [];
50
+
51
+ for (const messageView of messageViews) {
52
+ if (messageView.corrupted) {
53
+ pq.discardFifoMessage(messageView);
54
+ continue;
55
+ }
56
+
57
+ const messageGroup = messageView.messageGroup || '';
58
+ if (messageGroup) {
59
+ const group = groupedMessages.get(messageGroup) || [];
60
+ group.push(messageView);
61
+ groupedMessages.set(messageGroup, group);
62
+ } else {
63
+ ungroupedMessages.push(messageView);
64
+ }
65
+ }
66
+
67
+ // Process grouped messages (each group sequentially, groups in parallel)
68
+ for (const [ messageGroup, messages ] of groupedMessages.entries()) {
69
+ this.#processMessageGroup(pq, messageGroup, messages);
70
+ }
71
+
72
+ // Process ungrouped messages in parallel
73
+ for (const messageView of ungroupedMessages) {
74
+ this.consumeMessage(messageView)
75
+ .then(result => pq.eraseFifoMessage(messageView, result))
76
+ .catch(() => {
77
+ // Error already logged, continue with next message
78
+ });
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Process messages within the same group sequentially
84
+ */
85
+ async #processMessageGroup(pq: ProcessQueue, messageGroup: string, messages: MessageView[]): Promise<void> {
86
+ // Check if there's already processing happening for this group
87
+ const existingPromise = this.#groupProcessing.get(messageGroup);
88
+ const processTask = (async () => {
89
+ // Wait for previous processing to complete if any
90
+ if (existingPromise) {
91
+ await existingPromise.catch(() => {
92
+ // Ignore previous errors, continue processing
93
+ });
94
+ }
95
+
96
+ // Process messages in sequence
97
+ for (const messageView of messages) {
98
+ try {
99
+ const result = await this.consumeMessage(messageView);
100
+ await pq.eraseFifoMessage(messageView, result);
101
+ } catch (error) {
102
+ console.error('Failed to process FIFO message, messageGroup=%s, messageId=%s',
103
+ messageGroup, messageView.messageId, error);
104
+ // Continue with next message even if current fails
105
+ }
106
+ }
107
+ })();
108
+
109
+ // Store the promise for this group
110
+ this.#groupProcessing.set(messageGroup, processTask);
111
+
112
+ // Clean up when done
113
+ processTask.finally(() => {
114
+ this.#groupProcessing.delete(messageGroup);
115
+ });
116
+ }
117
+
118
+ #consumeIteratively(pq: ProcessQueue, messageViews: MessageView[], index: number): void {
119
+ if (index >= messageViews.length) {
120
+ return;
121
+ }
122
+
123
+ const messageView = messageViews[index];
124
+
125
+ if (messageView.corrupted) {
126
+ pq.discardFifoMessage(messageView);
127
+ this.#consumeIteratively(pq, messageViews, index + 1);
128
+ return;
129
+ }
130
+
131
+ this.consumeMessage(messageView)
132
+ .then(result => pq.eraseFifoMessage(messageView, result))
133
+ .then(() => this.#consumeIteratively(pq, messageViews, index + 1))
134
+ .catch(() => this.#consumeIteratively(pq, messageViews, index + 1));
135
+ }
136
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { FilterType, FilterExpression as FilterExpressionPB } from '../../proto/apache/rocketmq/v2/definition_pb';
19
+
20
+ const TAG_EXPRESSION_SUB_ALL = '*';
21
+
22
+ export class FilterExpression {
23
+ static readonly SUB_ALL = new FilterExpression(TAG_EXPRESSION_SUB_ALL);
24
+
25
+ readonly expression: string;
26
+ readonly filterType: FilterType;
27
+
28
+ constructor(expression: string, filterType = FilterType.TAG) {
29
+ this.expression = expression;
30
+ this.filterType = filterType;
31
+ }
32
+
33
+ toProtobuf() {
34
+ return new FilterExpressionPB()
35
+ .setType(this.filterType)
36
+ .setExpression(this.expression);
37
+ }
38
+
39
+ toString() {
40
+ return `FilterExpression(${this.filterType},${this.expression})`;
41
+ }
42
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { MessageView } from '../message';
19
+ import { ConsumeResult } from './ConsumeResult';
20
+
21
+ export interface MessageListener {
22
+ consume(messageView: MessageView): ConsumeResult | Promise<ConsumeResult>;
23
+ }