redis-consumer 1.1.3 → 1.1.6
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/dist/consumer.js +146 -144
- package/package.json +1 -1
package/dist/consumer.js
CHANGED
|
@@ -3,160 +3,162 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RedisConsumer = void 0;
|
|
4
4
|
const retry_processor_1 = require("./retry-processor");
|
|
5
5
|
class RedisConsumer {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
6
|
+
client;
|
|
7
|
+
originalClient;
|
|
8
|
+
state;
|
|
9
|
+
retryProcessor;
|
|
10
|
+
successfullMessages = new Map();
|
|
11
|
+
BLOCK;
|
|
12
|
+
COUNT;
|
|
13
|
+
RETRIES;
|
|
14
|
+
constructor(client, options = {}) {
|
|
15
|
+
this.originalClient = client;
|
|
16
|
+
this.client = client.duplicate();
|
|
17
|
+
this.state = {};
|
|
18
|
+
this.COUNT = options.COUNT ?? 1;
|
|
19
|
+
this.BLOCK = options.BLOCK ?? 0;
|
|
20
|
+
this.RETRIES = options.retries ?? 3;
|
|
21
|
+
this.retryProcessor = new retry_processor_1.RetryProcessor(this, {
|
|
22
|
+
retryTime: options.retryTime,
|
|
23
|
+
maxRetry: this.RETRIES,
|
|
24
|
+
});
|
|
25
|
+
this.client.connect();
|
|
26
|
+
}
|
|
27
|
+
set block(block) {
|
|
28
|
+
this.BLOCK = block;
|
|
29
|
+
}
|
|
30
|
+
set count(count) {
|
|
31
|
+
this.COUNT = count;
|
|
32
|
+
}
|
|
33
|
+
set retries(retries) {
|
|
34
|
+
this.RETRIES = retries;
|
|
35
|
+
}
|
|
36
|
+
get settings() {
|
|
37
|
+
return { block: this.BLOCK, count: this.COUNT };
|
|
38
|
+
}
|
|
39
|
+
async listen(streams) {
|
|
40
|
+
if (!Array.isArray(streams)) {
|
|
41
|
+
streams = [streams];
|
|
26
42
|
}
|
|
27
|
-
|
|
28
|
-
|
|
43
|
+
for (const stream of streams) {
|
|
44
|
+
const groupExists = await this.originalClient.groupExists(stream.name);
|
|
45
|
+
if (!groupExists) {
|
|
46
|
+
await this.originalClient.createGroup(stream.name);
|
|
47
|
+
}
|
|
48
|
+
if (this.hasStreamState(stream.name)) continue;
|
|
49
|
+
this.initStreamState(stream);
|
|
29
50
|
}
|
|
30
|
-
|
|
31
|
-
|
|
51
|
+
this.listenForStreams();
|
|
52
|
+
}
|
|
53
|
+
addAckMessage(stream, id) {
|
|
54
|
+
if (this.successfullMessages.has(stream)) {
|
|
55
|
+
const ackMessages = this.successfullMessages.get(stream);
|
|
56
|
+
ackMessages.push(id);
|
|
57
|
+
} else {
|
|
58
|
+
this.successfullMessages.set(stream, [id]);
|
|
32
59
|
}
|
|
33
|
-
|
|
34
|
-
|
|
60
|
+
}
|
|
61
|
+
async listenForStreams() {
|
|
62
|
+
const state = this.state;
|
|
63
|
+
const streamsToListen = [];
|
|
64
|
+
for (const stream in state) {
|
|
65
|
+
streamsToListen.push({ key: stream, id: state[stream].nextId });
|
|
35
66
|
}
|
|
36
|
-
|
|
37
|
-
|
|
67
|
+
const streamsMessages = await this.readStreams(streamsToListen);
|
|
68
|
+
if (!streamsMessages) {
|
|
69
|
+
await this.acknowlegdeMessages();
|
|
70
|
+
this.listenForStreams();
|
|
71
|
+
return;
|
|
38
72
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
streams = [streams];
|
|
42
|
-
}
|
|
43
|
-
for (const stream of streams) {
|
|
44
|
-
const groupExists = await this.originalClient.groupExists(stream.name);
|
|
45
|
-
if (!groupExists) {
|
|
46
|
-
await this.originalClient.createGroup(stream.name);
|
|
47
|
-
}
|
|
48
|
-
if (this.hasStreamState(stream.name))
|
|
49
|
-
continue;
|
|
50
|
-
this.initStreamState(stream);
|
|
51
|
-
}
|
|
52
|
-
this.listenForStreams();
|
|
53
|
-
}
|
|
54
|
-
addAckMessage(stream, id) {
|
|
55
|
-
if (this.successfullMessages.has(stream)) {
|
|
56
|
-
const ackMessages = this.successfullMessages.get(stream);
|
|
57
|
-
ackMessages.push(id);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
this.successfullMessages.set(stream, [id]);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
async listenForStreams() {
|
|
64
|
-
const state = this.state;
|
|
65
|
-
const streamsToListen = [];
|
|
66
|
-
for (const stream in state) {
|
|
67
|
-
streamsToListen.push({ key: stream, id: state[stream].nextId });
|
|
68
|
-
}
|
|
69
|
-
const streamsMessages = await this.readStreams(streamsToListen);
|
|
70
|
-
if (!streamsMessages) {
|
|
71
|
-
await this.acknowlegdeMessages();
|
|
72
|
-
this.listenForStreams();
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
for (const streamMessages of streamsMessages) {
|
|
76
|
-
await this.processStreamMessages(streamMessages);
|
|
77
|
-
}
|
|
78
|
-
this.listenForStreams();
|
|
73
|
+
for (const streamMessages of streamsMessages) {
|
|
74
|
+
await this.processStreamMessages(streamMessages);
|
|
79
75
|
}
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
this.listenForStreams();
|
|
77
|
+
}
|
|
78
|
+
hasStreamState(name) {
|
|
79
|
+
return !!this.getStreamState(name);
|
|
80
|
+
}
|
|
81
|
+
getStreamState(name) {
|
|
82
|
+
return this.state[name];
|
|
83
|
+
}
|
|
84
|
+
initStreamState(stream) {
|
|
85
|
+
const name = stream.name;
|
|
86
|
+
const executable = stream.executable;
|
|
87
|
+
let lastSuccessId;
|
|
88
|
+
if (stream.id) {
|
|
89
|
+
lastSuccessId = stream.id;
|
|
90
|
+
} else {
|
|
91
|
+
lastSuccessId = "0-0";
|
|
82
92
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
let nextId = lastSuccessId;
|
|
94
|
+
this.state[name] = { nextId, lastSuccessId, executable, recovering: true };
|
|
95
|
+
}
|
|
96
|
+
async readStreams(streamsToListen) {
|
|
97
|
+
const messages = await this.client.xReadGroup(
|
|
98
|
+
this.originalClient.groupName,
|
|
99
|
+
this.originalClient.clientName,
|
|
100
|
+
streamsToListen,
|
|
101
|
+
{ BLOCK: this.BLOCK, COUNT: this.COUNT },
|
|
102
|
+
);
|
|
103
|
+
return messages;
|
|
104
|
+
}
|
|
105
|
+
async processStreamMessages(streamMessages) {
|
|
106
|
+
const stream = streamMessages.name;
|
|
107
|
+
const state = this.getStreamState(stream);
|
|
108
|
+
if (!state)
|
|
109
|
+
throw new Error("No state was found for stream processing of " + stream);
|
|
110
|
+
const fnc = state.executable;
|
|
111
|
+
const messages = streamMessages.messages;
|
|
112
|
+
let msgids;
|
|
113
|
+
for (const message of messages) {
|
|
114
|
+
try {
|
|
115
|
+
await fnc(message, stream);
|
|
116
|
+
// this.addAckMessage(stream, message.id);
|
|
117
|
+
msgids = [message.id];
|
|
118
|
+
const ackid = await this.originalClient.xAck(
|
|
119
|
+
stream,
|
|
120
|
+
this.originalClient.groupName,
|
|
121
|
+
msgids,
|
|
122
|
+
);
|
|
123
|
+
ackid && (await this.originalClient.xDel(stream, msgids));
|
|
124
|
+
} catch (err) {
|
|
125
|
+
// console.error(err);
|
|
126
|
+
this.client.emit("process-error", err, { stream, message, retries: 0 });
|
|
127
|
+
if (this.RETRIES === 0) continue;
|
|
128
|
+
if (err instanceof Error) {
|
|
129
|
+
this.retryProcessor.add(err, stream, message, fnc);
|
|
130
|
+
} else {
|
|
131
|
+
const newErr = new Error(String(err));
|
|
132
|
+
this.retryProcessor.add(newErr, stream, message, fnc);
|
|
90
133
|
}
|
|
134
|
+
}
|
|
91
135
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
let nextId = lastSuccessId;
|
|
103
|
-
this.state[name] = { nextId, lastSuccessId, executable, recovering: true };
|
|
136
|
+
// await this.acknowlegdeMessages();
|
|
137
|
+
const recovering = state.recovering;
|
|
138
|
+
if (recovering && messages.length === 0) {
|
|
139
|
+
state.nextId = ">";
|
|
140
|
+
state.recovering = false;
|
|
141
|
+
} else if (recovering) {
|
|
142
|
+
const lastMessage = messages.slice(-1);
|
|
143
|
+
const lastId = lastMessage[0].id;
|
|
144
|
+
state.nextId = lastId;
|
|
104
145
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
await fnc(message, stream);
|
|
122
|
-
this.addAckMessage(stream, message.id);
|
|
123
|
-
}
|
|
124
|
-
catch (err) {
|
|
125
|
-
this.client.emit('process-error', err, { stream, message, retries: 0 });
|
|
126
|
-
if (this.RETRIES === 0)
|
|
127
|
-
continue;
|
|
128
|
-
if (err instanceof Error) {
|
|
129
|
-
this.retryProcessor.add(err, stream, message, fnc);
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
const newErr = new Error(String(err));
|
|
133
|
-
this.retryProcessor.add(newErr, stream, message, fnc);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
await this.acknowlegdeMessages();
|
|
138
|
-
const recovering = state.recovering;
|
|
139
|
-
if (recovering && messages.length === 0) {
|
|
140
|
-
state.nextId = '>';
|
|
141
|
-
state.recovering = false;
|
|
142
|
-
}
|
|
143
|
-
else if (recovering) {
|
|
144
|
-
const lastMessage = messages.slice(-1);
|
|
145
|
-
const lastId = lastMessage[0].id;
|
|
146
|
-
state.nextId = lastId;
|
|
147
|
-
}
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
150
|
-
async acknowlegdeMessages() {
|
|
151
|
-
for (const item of this.successfullMessages) {
|
|
152
|
-
const stream = item[0];
|
|
153
|
-
const ackMessages = item[1];
|
|
154
|
-
const id = await this.originalClient.xAck(stream, this.originalClient.groupName, ackMessages);
|
|
155
|
-
if (id) {
|
|
156
|
-
this.successfullMessages.delete(stream);
|
|
157
|
-
this.originalClient.xDel(stream, ackMessages);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
async acknowlegdeMessages() {
|
|
149
|
+
for (const item of this.successfullMessages) {
|
|
150
|
+
const stream = item[0];
|
|
151
|
+
const ackMessages = item[1];
|
|
152
|
+
const id = await this.originalClient.xAck(
|
|
153
|
+
stream,
|
|
154
|
+
this.originalClient.groupName,
|
|
155
|
+
ackMessages,
|
|
156
|
+
);
|
|
157
|
+
if (id) {
|
|
158
|
+
this.successfullMessages.delete(stream);
|
|
159
|
+
await this.originalClient.xDel(stream, ackMessages);
|
|
160
|
+
}
|
|
160
161
|
}
|
|
162
|
+
}
|
|
161
163
|
}
|
|
162
164
|
exports.RedisConsumer = RedisConsumer;
|