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.
- package/LICENSE +201 -0
- package/README.md +186 -0
- package/dist/client/BaseClient.d.ts +95 -0
- package/dist/client/BaseClient.js +324 -0
- package/dist/client/ClientId.d.ts +24 -0
- package/dist/client/ClientId.js +33 -0
- package/dist/client/Logger.d.ts +25 -0
- package/dist/client/Logger.js +33 -0
- package/dist/client/RpcClient.d.ts +48 -0
- package/dist/client/RpcClient.js +219 -0
- package/dist/client/RpcClientManager.d.ts +42 -0
- package/dist/client/RpcClientManager.js +144 -0
- package/dist/client/SessionCredentials.d.ts +21 -0
- package/dist/client/SessionCredentials.js +19 -0
- package/dist/client/Settings.d.ts +31 -0
- package/dist/client/Settings.js +40 -0
- package/dist/client/TelemetrySession.d.ts +27 -0
- package/dist/client/TelemetrySession.js +110 -0
- package/dist/client/UserAgent.d.ts +25 -0
- package/dist/client/UserAgent.js +47 -0
- package/dist/client/index.d.ts +26 -0
- package/dist/client/index.js +43 -0
- package/dist/consumer/Assignment.d.ts +23 -0
- package/dist/consumer/Assignment.js +40 -0
- package/dist/consumer/Assignments.d.ts +24 -0
- package/dist/consumer/Assignments.js +47 -0
- package/dist/consumer/ConsumeResult.d.ts +20 -0
- package/dist/consumer/ConsumeResult.js +25 -0
- package/dist/consumer/ConsumeService.d.ts +28 -0
- package/dist/consumer/ConsumeService.js +49 -0
- package/dist/consumer/ConsumeTask.d.ts +24 -0
- package/dist/consumer/ConsumeTask.js +40 -0
- package/dist/consumer/Consumer.d.ts +38 -0
- package/dist/consumer/Consumer.js +111 -0
- package/dist/consumer/FifoConsumeService.d.ts +25 -0
- package/dist/consumer/FifoConsumeService.js +123 -0
- package/dist/consumer/FilterExpression.d.ts +25 -0
- package/dist/consumer/FilterExpression.js +40 -0
- package/dist/consumer/MessageListener.d.ts +21 -0
- package/dist/consumer/MessageListener.js +19 -0
- package/dist/consumer/ProcessQueue.d.ts +39 -0
- package/dist/consumer/ProcessQueue.js +286 -0
- package/dist/consumer/PushConsumer.d.ts +68 -0
- package/dist/consumer/PushConsumer.js +377 -0
- package/dist/consumer/PushSubscriptionSettings.d.ts +31 -0
- package/dist/consumer/PushSubscriptionSettings.js +97 -0
- package/dist/consumer/SimpleConsumer.d.ts +50 -0
- package/dist/consumer/SimpleConsumer.js +122 -0
- package/dist/consumer/SimpleSubscriptionSettings.d.ts +28 -0
- package/dist/consumer/SimpleSubscriptionSettings.js +57 -0
- package/dist/consumer/StandardConsumeService.d.ts +24 -0
- package/dist/consumer/StandardConsumeService.js +42 -0
- package/dist/consumer/SubscriptionLoadBalancer.d.ts +23 -0
- package/dist/consumer/SubscriptionLoadBalancer.js +46 -0
- package/dist/consumer/index.d.ts +32 -0
- package/dist/consumer/index.js +49 -0
- package/dist/exception/BadRequestException.d.ts +20 -0
- package/dist/exception/BadRequestException.js +28 -0
- package/dist/exception/ClientException.d.ts +20 -0
- package/dist/exception/ClientException.js +31 -0
- package/dist/exception/ForbiddenException.d.ts +20 -0
- package/dist/exception/ForbiddenException.js +28 -0
- package/dist/exception/InternalErrorException.d.ts +20 -0
- package/dist/exception/InternalErrorException.js +28 -0
- package/dist/exception/NotFoundException.d.ts +20 -0
- package/dist/exception/NotFoundException.js +28 -0
- package/dist/exception/PayloadTooLargeException.d.ts +20 -0
- package/dist/exception/PayloadTooLargeException.js +28 -0
- package/dist/exception/PaymentRequiredException.d.ts +20 -0
- package/dist/exception/PaymentRequiredException.js +28 -0
- package/dist/exception/ProxyTimeoutException.d.ts +20 -0
- package/dist/exception/ProxyTimeoutException.js +28 -0
- package/dist/exception/RequestHeaderFieldsTooLargeException.d.ts +20 -0
- package/dist/exception/RequestHeaderFieldsTooLargeException.js +28 -0
- package/dist/exception/StatusChecker.d.ts +20 -0
- package/dist/exception/StatusChecker.js +98 -0
- package/dist/exception/TooManyRequestsException.d.ts +20 -0
- package/dist/exception/TooManyRequestsException.js +28 -0
- package/dist/exception/UnauthorizedException.d.ts +20 -0
- package/dist/exception/UnauthorizedException.js +28 -0
- package/dist/exception/UnsupportedException.d.ts +20 -0
- package/dist/exception/UnsupportedException.js +28 -0
- package/dist/exception/index.d.ts +29 -0
- package/dist/exception/index.js +46 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +39 -0
- package/dist/message/Message.d.ts +38 -0
- package/dist/message/Message.js +57 -0
- package/dist/message/MessageId.d.ts +59 -0
- package/dist/message/MessageId.js +123 -0
- package/dist/message/MessageView.d.ts +38 -0
- package/dist/message/MessageView.js +90 -0
- package/dist/message/PublishingMessage.d.ts +30 -0
- package/dist/message/PublishingMessage.js +100 -0
- package/dist/message/index.d.ts +20 -0
- package/dist/message/index.js +37 -0
- package/dist/producer/Producer.d.ts +55 -0
- package/dist/producer/Producer.js +318 -0
- package/dist/producer/PublishingLoadBalancer.d.ts +24 -0
- package/dist/producer/PublishingLoadBalancer.js +82 -0
- package/dist/producer/PublishingSettings.d.ts +28 -0
- package/dist/producer/PublishingSettings.js +70 -0
- package/dist/producer/RecallReceipt.d.ts +25 -0
- package/dist/producer/RecallReceipt.js +34 -0
- package/dist/producer/SendReceipt.d.ts +29 -0
- package/dist/producer/SendReceipt.js +60 -0
- package/dist/producer/Transaction.d.ts +28 -0
- package/dist/producer/Transaction.js +70 -0
- package/dist/producer/TransactionChecker.d.ts +21 -0
- package/dist/producer/TransactionChecker.js +19 -0
- package/dist/producer/index.d.ts +22 -0
- package/dist/producer/index.js +40 -0
- package/dist/retry/ExponentialBackoffRetryPolicy.d.ts +27 -0
- package/dist/retry/ExponentialBackoffRetryPolicy.js +64 -0
- package/dist/retry/RetryPolicy.d.ts +46 -0
- package/dist/retry/RetryPolicy.js +19 -0
- package/dist/retry/index.d.ts +18 -0
- package/dist/retry/index.js +35 -0
- package/dist/route/Broker.d.ts +25 -0
- package/dist/route/Broker.js +40 -0
- package/dist/route/Endpoints.d.ts +30 -0
- package/dist/route/Endpoints.js +71 -0
- package/dist/route/MessageQueue.d.ts +27 -0
- package/dist/route/MessageQueue.js +47 -0
- package/dist/route/TopicRouteData.d.ts +24 -0
- package/dist/route/TopicRouteData.js +37 -0
- package/dist/route/index.d.ts +20 -0
- package/dist/route/index.js +37 -0
- package/dist/util/index.d.ts +35 -0
- package/dist/util/index.js +88 -0
- package/package.json +62 -0
- package/proto/apache/rocketmq/v2/admin.proto +43 -0
- package/proto/apache/rocketmq/v2/admin_grpc_pb.d.ts +41 -0
- package/proto/apache/rocketmq/v2/admin_grpc_pb.js +60 -0
- package/proto/apache/rocketmq/v2/admin_pb.d.ts +56 -0
- package/proto/apache/rocketmq/v2/admin_pb.js +340 -0
- package/proto/apache/rocketmq/v2/definition.proto +570 -0
- package/proto/apache/rocketmq/v2/definition_grpc_pb.js +1 -0
- package/proto/apache/rocketmq/v2/definition_pb.d.ts +885 -0
- package/proto/apache/rocketmq/v2/definition_pb.js +6141 -0
- package/proto/apache/rocketmq/v2/service.proto +443 -0
- package/proto/apache/rocketmq/v2/service_grpc_pb.d.ts +294 -0
- package/proto/apache/rocketmq/v2/service_grpc_pb.js +637 -0
- package/proto/apache/rocketmq/v2/service_pb.d.ts +1249 -0
- package/proto/apache/rocketmq/v2/service_pb.js +9723 -0
- package/src/client/BaseClient.ts +404 -0
- package/src/client/ClientId.ts +31 -0
- package/src/client/Logger.ts +36 -0
- package/src/client/RpcClient.ts +258 -0
- package/src/client/RpcClientManager.ts +180 -0
- package/src/client/SessionCredentials.ts +22 -0
- package/src/client/Settings.ts +46 -0
- package/src/client/TelemetrySession.ts +130 -0
- package/src/client/UserAgent.ts +45 -0
- package/src/client/index.ts +27 -0
- package/src/consumer/Assignment.ts +39 -0
- package/src/consumer/Assignments.ts +46 -0
- package/src/consumer/ConsumeResult.ts +21 -0
- package/src/consumer/ConsumeService.ts +54 -0
- package/src/consumer/ConsumeTask.ts +40 -0
- package/src/consumer/Consumer.ts +129 -0
- package/src/consumer/FifoConsumeService.ts +136 -0
- package/src/consumer/FilterExpression.ts +42 -0
- package/src/consumer/MessageListener.ts +23 -0
- package/src/consumer/ProcessQueue.ts +326 -0
- package/src/consumer/PushConsumer.ts +473 -0
- package/src/consumer/PushSubscriptionSettings.ts +123 -0
- package/src/consumer/SimpleConsumer.ts +153 -0
- package/src/consumer/SimpleSubscriptionSettings.ts +64 -0
- package/src/consumer/StandardConsumeService.ts +44 -0
- package/src/consumer/SubscriptionLoadBalancer.ts +47 -0
- package/src/consumer/index.ts +33 -0
- package/src/exception/BadRequestException.ts +25 -0
- package/src/exception/ClientException.ts +29 -0
- package/src/exception/ForbiddenException.ts +25 -0
- package/src/exception/InternalErrorException.ts +25 -0
- package/src/exception/NotFoundException.ts +25 -0
- package/src/exception/PayloadTooLargeException.ts +25 -0
- package/src/exception/PaymentRequiredException.ts +25 -0
- package/src/exception/ProxyTimeoutException.ts +25 -0
- package/src/exception/RequestHeaderFieldsTooLargeException.ts +25 -0
- package/src/exception/StatusChecker.ts +94 -0
- package/src/exception/TooManyRequestsException.ts +25 -0
- package/src/exception/UnauthorizedException.ts +25 -0
- package/src/exception/UnsupportedException.ts +25 -0
- package/src/exception/index.ts +30 -0
- package/src/index.ts +23 -0
- package/src/message/Message.ts +67 -0
- package/src/message/MessageId.ts +123 -0
- package/src/message/MessageView.ts +94 -0
- package/src/message/PublishingMessage.ts +104 -0
- package/src/message/index.ts +21 -0
- package/src/producer/Producer.ts +388 -0
- package/src/producer/PublishingLoadBalancer.ts +85 -0
- package/src/producer/PublishingSettings.ts +78 -0
- package/src/producer/RecallReceipt.ts +32 -0
- package/src/producer/SendReceipt.ts +63 -0
- package/src/producer/Transaction.ts +86 -0
- package/src/producer/TransactionChecker.ts +23 -0
- package/src/producer/index.ts +24 -0
- package/src/retry/ExponentialBackoffRetryPolicy.ts +76 -0
- package/src/retry/RetryPolicy.ts +51 -0
- package/src/retry/index.ts +19 -0
- package/src/route/Broker.ts +39 -0
- package/src/route/Endpoints.ts +70 -0
- package/src/route/MessageQueue.ts +49 -0
- package/src/route/TopicRouteData.ts +38 -0
- package/src/route/index.ts +21 -0
- 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
|
+
}
|