@juzi/wechaty-puppet-service 1.0.130 → 1.0.131
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/cjs/src/auth/call-cred.d.ts +2 -2
- package/dist/cjs/src/auth/call-cred.d.ts.map +1 -1
- package/dist/cjs/src/auth/call-cred.js.map +1 -1
- package/dist/cjs/src/client/puppet-service.d.ts +25 -2
- package/dist/cjs/src/client/puppet-service.d.ts.map +1 -1
- package/dist/cjs/src/client/puppet-service.js +389 -124
- package/dist/cjs/src/client/puppet-service.js.map +1 -1
- package/dist/cjs/src/client/room-cache-coordinator.d.ts +14 -0
- package/dist/cjs/src/client/room-cache-coordinator.d.ts.map +1 -0
- package/dist/cjs/src/client/room-cache-coordinator.js +53 -0
- package/dist/cjs/src/client/room-cache-coordinator.js.map +1 -0
- package/dist/cjs/src/client/room-member-cache.spec.d.ts +2 -0
- package/dist/cjs/src/client/room-member-cache.spec.d.ts.map +1 -0
- package/dist/cjs/src/client/room-member-cache.spec.js +417 -0
- package/dist/cjs/src/client/room-member-cache.spec.js.map +1 -0
- package/dist/cjs/src/client/room-member-load.spec.d.ts +2 -0
- package/dist/cjs/src/client/room-member-load.spec.d.ts.map +1 -0
- package/dist/cjs/src/client/room-member-load.spec.js +324 -0
- package/dist/cjs/src/client/room-member-load.spec.js.map +1 -0
- package/dist/cjs/src/package-json.js +4 -4
- package/dist/cjs/src/server/event-stream-manager.d.ts.map +1 -1
- package/dist/cjs/src/server/event-stream-manager.js +16 -0
- package/dist/cjs/src/server/event-stream-manager.js.map +1 -1
- package/dist/cjs/src/server/puppet-implementation.d.ts.map +1 -1
- package/dist/cjs/src/server/puppet-implementation.js +91 -28
- package/dist/cjs/src/server/puppet-implementation.js.map +1 -1
- package/dist/cjs/src/utils/pb-payload-helper.d.ts +10 -0
- package/dist/cjs/src/utils/pb-payload-helper.d.ts.map +1 -1
- package/dist/cjs/src/utils/pb-payload-helper.js +180 -1
- package/dist/cjs/src/utils/pb-payload-helper.js.map +1 -1
- package/dist/cjs/src/utils/room-member-load.spec.d.ts +2 -0
- package/dist/cjs/src/utils/room-member-load.spec.d.ts.map +1 -0
- package/dist/cjs/src/utils/room-member-load.spec.js +83 -0
- package/dist/cjs/src/utils/room-member-load.spec.js.map +1 -0
- package/dist/esm/src/auth/call-cred.d.ts +2 -2
- package/dist/esm/src/auth/call-cred.d.ts.map +1 -1
- package/dist/esm/src/auth/call-cred.js.map +1 -1
- package/dist/esm/src/client/puppet-service.d.ts +25 -2
- package/dist/esm/src/client/puppet-service.d.ts.map +1 -1
- package/dist/esm/src/client/puppet-service.js +390 -125
- package/dist/esm/src/client/puppet-service.js.map +1 -1
- package/dist/esm/src/client/room-cache-coordinator.d.ts +14 -0
- package/dist/esm/src/client/room-cache-coordinator.d.ts.map +1 -0
- package/dist/esm/src/client/room-cache-coordinator.js +49 -0
- package/dist/esm/src/client/room-cache-coordinator.js.map +1 -0
- package/dist/esm/src/client/room-member-cache.spec.d.ts +2 -0
- package/dist/esm/src/client/room-member-cache.spec.d.ts.map +1 -0
- package/dist/esm/src/client/room-member-cache.spec.js +415 -0
- package/dist/esm/src/client/room-member-cache.spec.js.map +1 -0
- package/dist/esm/src/client/room-member-load.spec.d.ts +2 -0
- package/dist/esm/src/client/room-member-load.spec.d.ts.map +1 -0
- package/dist/esm/src/client/room-member-load.spec.js +296 -0
- package/dist/esm/src/client/room-member-load.spec.js.map +1 -0
- package/dist/esm/src/package-json.js +4 -4
- package/dist/esm/src/server/event-stream-manager.d.ts.map +1 -1
- package/dist/esm/src/server/event-stream-manager.js +16 -0
- package/dist/esm/src/server/event-stream-manager.js.map +1 -1
- package/dist/esm/src/server/puppet-implementation.d.ts.map +1 -1
- package/dist/esm/src/server/puppet-implementation.js +92 -29
- package/dist/esm/src/server/puppet-implementation.js.map +1 -1
- package/dist/esm/src/utils/pb-payload-helper.d.ts +10 -0
- package/dist/esm/src/utils/pb-payload-helper.d.ts.map +1 -1
- package/dist/esm/src/utils/pb-payload-helper.js +169 -0
- package/dist/esm/src/utils/pb-payload-helper.js.map +1 -1
- package/dist/esm/src/utils/room-member-load.spec.d.ts +2 -0
- package/dist/esm/src/utils/room-member-load.spec.d.ts.map +1 -0
- package/dist/esm/src/utils/room-member-load.spec.js +58 -0
- package/dist/esm/src/utils/room-member-load.spec.js.map +1 -0
- package/package.json +4 -4
- package/src/auth/call-cred.ts +1 -1
- package/src/client/puppet-service.ts +324 -138
- package/src/client/room-cache-coordinator.ts +50 -0
- package/src/client/room-member-cache.spec.ts +448 -0
- package/src/client/room-member-load.spec.ts +319 -0
- package/src/package-json.ts +4 -4
- package/src/server/event-stream-manager.ts +15 -0
- package/src/server/puppet-implementation.ts +94 -29
- package/src/utils/pb-payload-helper.ts +150 -0
- package/src/utils/room-member-load.spec.ts +67 -0
|
@@ -57,6 +57,7 @@ const event_type_rev_js_1 = require("../event-type-rev.js");
|
|
|
57
57
|
const package_json_js_1 = require("../package-json.js");
|
|
58
58
|
const grpc_manager_js_1 = require("./grpc-manager.js");
|
|
59
59
|
const payload_store_js_1 = require("./payload-store.js");
|
|
60
|
+
const room_cache_coordinator_js_1 = require("./room-cache-coordinator.js");
|
|
60
61
|
const pb_payload_helper_js_1 = require("../utils/pb-payload-helper.js");
|
|
61
62
|
const call_media_mapping_js_1 = require("../utils/call-media-mapping.js");
|
|
62
63
|
const gerror_1 = require("gerror");
|
|
@@ -76,6 +77,15 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
76
77
|
options;
|
|
77
78
|
static VERSION = config_js_1.VERSION;
|
|
78
79
|
_payloadStore;
|
|
80
|
+
roomCache = new room_cache_coordinator_js_1.RoomCacheCoordinator();
|
|
81
|
+
eventQueue = Promise.resolve();
|
|
82
|
+
eventEpoch = 0;
|
|
83
|
+
eventsBlocked = false;
|
|
84
|
+
failedEventSeq;
|
|
85
|
+
activeEventSeq;
|
|
86
|
+
pendingEventSeq;
|
|
87
|
+
checkpointQueue = Promise.resolve();
|
|
88
|
+
pendingCheckpointRollback;
|
|
79
89
|
timeoutMilliseconds;
|
|
80
90
|
_grpcManager;
|
|
81
91
|
get grpcManager() {
|
|
@@ -129,6 +139,8 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
129
139
|
this.log.verbose('PuppetService', 'onStart()');
|
|
130
140
|
this.waitingForLogin = false;
|
|
131
141
|
this.waitingForReady = false;
|
|
142
|
+
this.suspendEventProcessing();
|
|
143
|
+
this.eventsBlocked = false;
|
|
132
144
|
if (this._grpcManager) {
|
|
133
145
|
this.log.warn('PuppetService', 'onStart() found this.grpc is already existed. dropped.');
|
|
134
146
|
this._grpcManager = undefined;
|
|
@@ -145,7 +157,7 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
145
157
|
this.bridgeGrpcEventStream(grpcManager);
|
|
146
158
|
this.log.info('PuppetService', 'start() setting up bridge grpc event stream ... done');
|
|
147
159
|
this.log.info('PuppetService', 'start() starting grpc manager...');
|
|
148
|
-
const { lastEventSeq, accountId } = await this.
|
|
160
|
+
const { lastEventSeq, accountId } = await this.eventResumePosition();
|
|
149
161
|
await grpcManager.start(lastEventSeq, accountId);
|
|
150
162
|
this.log.info('PuppetService', 'start() starting grpc manager... done');
|
|
151
163
|
this.log.info('PuppetService', 'start healthCheck');
|
|
@@ -154,6 +166,8 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
154
166
|
}
|
|
155
167
|
async onStop() {
|
|
156
168
|
this.log.info('PuppetService', 'onStop()');
|
|
169
|
+
this.suspendEventProcessing();
|
|
170
|
+
await this.checkpointQueue;
|
|
157
171
|
if (this._grpcManager) {
|
|
158
172
|
this.log.info('PuppetService', 'onStop() stopping grpc manager ...');
|
|
159
173
|
const grpcManager = this._grpcManager;
|
|
@@ -189,7 +203,41 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
189
203
|
bridgeGrpcEventStream(client) {
|
|
190
204
|
this.log.verbose('PuppetService', 'bridgeGrpcEventStream(client)');
|
|
191
205
|
client
|
|
192
|
-
.on('data',
|
|
206
|
+
.on('data', (event) => {
|
|
207
|
+
if (client !== this._grpcManager || this.eventsBlocked) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const epoch = this.eventEpoch;
|
|
211
|
+
this.eventQueue = this.eventQueue.then(async () => {
|
|
212
|
+
if (!this.ownsEventWorker(client, epoch)) {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
this.activeEventSeq = event.getSeq();
|
|
216
|
+
try {
|
|
217
|
+
if (this.failedEventSeq !== undefined && event.getSeq() > this.failedEventSeq) {
|
|
218
|
+
throw new Error(`Replay skipped failed event ${this.failedEventSeq}; stream halted until reset`);
|
|
219
|
+
}
|
|
220
|
+
await this.onGrpcStreamEvent(event, epoch);
|
|
221
|
+
if (!this.ownsEventWorker(client, epoch)) {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
if (event.getSeq() === this.failedEventSeq) {
|
|
225
|
+
this.failedEventSeq = undefined;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
if (!this.ownsEventWorker(client, epoch)) {
|
|
230
|
+
this.log.error('PuppetService', 'superseded event worker failed: %s', error);
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
this.haltEventStream(client, event, error);
|
|
234
|
+
}
|
|
235
|
+
if (epoch === this.eventEpoch) {
|
|
236
|
+
this.activeEventSeq = undefined;
|
|
237
|
+
}
|
|
238
|
+
return undefined;
|
|
239
|
+
}).catch((error) => { this.reportStreamError(error); });
|
|
240
|
+
})
|
|
193
241
|
.on('end', () => {
|
|
194
242
|
this.log.verbose('PuppetService', 'bridgeGrpcEventStream() eventStream.on(end)');
|
|
195
243
|
})
|
|
@@ -214,7 +262,128 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
214
262
|
this.log.verbose('PuppetService', 'bridgeGrpcEventStream() eventStream.on(cancel), %s', JSON.stringify(args));
|
|
215
263
|
});
|
|
216
264
|
}
|
|
217
|
-
|
|
265
|
+
suspendEventProcessing() {
|
|
266
|
+
if (this.activeEventSeq) {
|
|
267
|
+
this.pendingEventSeq ??= this.activeEventSeq;
|
|
268
|
+
}
|
|
269
|
+
this.eventEpoch++;
|
|
270
|
+
this.eventsBlocked = true;
|
|
271
|
+
this.activeEventSeq = undefined;
|
|
272
|
+
this.eventQueue = Promise.resolve();
|
|
273
|
+
}
|
|
274
|
+
ownsEventWorker(manager, epoch) {
|
|
275
|
+
return manager === this._grpcManager && this.isEventEpochCurrent(epoch);
|
|
276
|
+
}
|
|
277
|
+
isEventEpochCurrent(epoch) {
|
|
278
|
+
return epoch === this.eventEpoch && !this.eventsBlocked;
|
|
279
|
+
}
|
|
280
|
+
async eventResumePosition(epoch = this.eventEpoch) {
|
|
281
|
+
return this.withEventCheckpoint(async () => {
|
|
282
|
+
if (this.pendingCheckpointRollback) {
|
|
283
|
+
await this.restoreEventMetadata(this.pendingCheckpointRollback);
|
|
284
|
+
this.pendingCheckpointRollback = undefined;
|
|
285
|
+
}
|
|
286
|
+
const lastEventSeq = await this._payloadStore.miscellaneous?.get('lastEventSeq');
|
|
287
|
+
if (epoch !== this.eventEpoch) {
|
|
288
|
+
return { lastEventSeq };
|
|
289
|
+
}
|
|
290
|
+
if (this.pendingEventSeq !== undefined && this.pendingEventSeq > Number(lastEventSeq ?? 0)) {
|
|
291
|
+
this.failedEventSeq ??= this.pendingEventSeq;
|
|
292
|
+
}
|
|
293
|
+
this.pendingEventSeq = undefined;
|
|
294
|
+
return { lastEventSeq, accountId: await this._payloadStore.miscellaneous?.get('accountId') };
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
async withEventCheckpoint(operation) {
|
|
298
|
+
const result = this.checkpointQueue.then(operation);
|
|
299
|
+
this.checkpointQueue = result.then(() => undefined, () => undefined);
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
async restoreEventMetadata(previous) {
|
|
303
|
+
for (const [key, value] of previous) {
|
|
304
|
+
if (value === undefined) {
|
|
305
|
+
await this._payloadStore.miscellaneous?.delete(key);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
await this._payloadStore.miscellaneous?.set(key, value);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
async writeEventMetadata(changes, epoch) {
|
|
313
|
+
const isCurrent = () => epoch === undefined || this.isEventEpochCurrent(epoch);
|
|
314
|
+
if (!isCurrent()) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const previous = new Map();
|
|
318
|
+
for (const key of changes.keys()) {
|
|
319
|
+
previous.set(key, await this._payloadStore.miscellaneous?.get(key));
|
|
320
|
+
}
|
|
321
|
+
if (!isCurrent()) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
for (const [key, value] of changes) {
|
|
326
|
+
if (value === undefined) {
|
|
327
|
+
await this._payloadStore.miscellaneous?.delete(key);
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
await this._payloadStore.miscellaneous?.set(key, value);
|
|
331
|
+
}
|
|
332
|
+
if (!isCurrent()) {
|
|
333
|
+
await this.restoreEventMetadata(previous);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
try {
|
|
340
|
+
await this.restoreEventMetadata(previous);
|
|
341
|
+
}
|
|
342
|
+
catch (rollbackError) {
|
|
343
|
+
this.pendingCheckpointRollback = previous;
|
|
344
|
+
this.log.error('PuppetService', 'checkpoint rollback failed: %s', rollbackError);
|
|
345
|
+
}
|
|
346
|
+
throw error;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
async commitEventCheckpoint(seq, timestamp, epoch) {
|
|
350
|
+
await this.withEventCheckpoint(async () => {
|
|
351
|
+
if (!this.isEventEpochCurrent(epoch)) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const lastEventSeq = await this._payloadStore.miscellaneous?.get('lastEventSeq');
|
|
355
|
+
if (lastEventSeq && seq <= Number(lastEventSeq) && seq !== 1) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
await this.writeEventMetadata(new Map([
|
|
359
|
+
['lastEventTimestamp', timestamp], ['lastEventSeq', String(seq)],
|
|
360
|
+
]), epoch);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
reportStreamError(error) {
|
|
364
|
+
this.log.error('PuppetService', 'event processing failed: %s', error);
|
|
365
|
+
try {
|
|
366
|
+
this.emit('error', error);
|
|
367
|
+
}
|
|
368
|
+
catch (listenerError) {
|
|
369
|
+
this.log.error('PuppetService', 'error listener failed: %s', listenerError);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
haltEventStream(manager, event, error) {
|
|
373
|
+
this.failedEventSeq ??= event.getSeq();
|
|
374
|
+
this.suspendEventProcessing();
|
|
375
|
+
try {
|
|
376
|
+
manager.stopStream();
|
|
377
|
+
}
|
|
378
|
+
catch (stopError) {
|
|
379
|
+
this.log.error('PuppetService', 'stopping failed event stream failed: %s', stopError);
|
|
380
|
+
}
|
|
381
|
+
this.reportStreamError(error);
|
|
382
|
+
}
|
|
383
|
+
async onGrpcStreamEvent(event, epoch = this.eventEpoch) {
|
|
384
|
+
if (!this.isEventEpochCurrent(epoch)) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
218
387
|
const type = event.getType();
|
|
219
388
|
const payload = event.getPayload();
|
|
220
389
|
const seq = event.getSeq();
|
|
@@ -228,15 +397,6 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
228
397
|
data: `onGrpcStreamEvent(${event_type_rev_js_1.EventTypeRev[type]})`,
|
|
229
398
|
});
|
|
230
399
|
}
|
|
231
|
-
if (seq && !config_js_1.envVars.WECHATY_PUPPET_SERVICE_DISABLE_EVENT_CACHE()) {
|
|
232
|
-
const { lastEventSeq } = await this.getMiscellaneousStoreData();
|
|
233
|
-
if (!lastEventSeq || (seq > Number(lastEventSeq) || seq === 1)) {
|
|
234
|
-
await this.setMiscellaneousStoreData({
|
|
235
|
-
lastEventSeq: seq.toString(),
|
|
236
|
-
lastEventTimestamp: timestamp,
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
400
|
switch (type) {
|
|
241
401
|
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_DONG:
|
|
242
402
|
this.emit('dong', JSON.parse(payload));
|
|
@@ -259,11 +419,14 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
259
419
|
const loginPayload = JSON.parse(payload);
|
|
260
420
|
if (!config_js_1.envVars.WECHATY_PUPPET_SERVICE_DISABLE_EVENT_CACHE()) {
|
|
261
421
|
const { accountId } = await this.getMiscellaneousStoreData();
|
|
422
|
+
if (!this.isEventEpochCurrent(epoch)) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
262
425
|
if (accountId !== loginPayload.contactId) {
|
|
263
|
-
await this.resetMiscellaneousStoreData();
|
|
426
|
+
await this.resetMiscellaneousStoreData(epoch);
|
|
264
427
|
await this.setMiscellaneousStoreData({
|
|
265
428
|
accountId: loginPayload.contactId,
|
|
266
|
-
});
|
|
429
|
+
}, epoch);
|
|
267
430
|
}
|
|
268
431
|
}
|
|
269
432
|
(async () => this.login(loginPayload.contactId))().catch(e => this.log.error('PuppetService', 'onGrpcStreamEvent() this.login() rejection %s', e.message));
|
|
@@ -273,7 +436,7 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
273
436
|
{
|
|
274
437
|
const logoutPayload = JSON.parse(payload);
|
|
275
438
|
if (!config_js_1.envVars.WECHATY_PUPPET_SERVICE_DISABLE_EVENT_CACHE()) {
|
|
276
|
-
await this.resetMiscellaneousStoreData();
|
|
439
|
+
await this.resetMiscellaneousStoreData(epoch);
|
|
277
440
|
}
|
|
278
441
|
;
|
|
279
442
|
(async () => this.logout(logoutPayload.data))().catch(e => this.log.error('PuppetService', 'onGrpcStreamEvent() this.logout() rejection %s', e.message));
|
|
@@ -281,8 +444,25 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
281
444
|
break;
|
|
282
445
|
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_DIRTY:
|
|
283
446
|
await this.fastDirty(JSON.parse(payload));
|
|
447
|
+
if (!this.isEventEpochCurrent(epoch)) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
284
450
|
this.emit('dirty', JSON.parse(payload));
|
|
285
451
|
break;
|
|
452
|
+
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_ROOM_MEMBER_LOAD: {
|
|
453
|
+
const loadPayload = JSON.parse(payload);
|
|
454
|
+
(0, pb_payload_helper_js_1.validateRoomMemberLoadState)(loadPayload);
|
|
455
|
+
this.roomCache.invalidate(loadPayload.roomId);
|
|
456
|
+
await this.roomCache.run(loadPayload.roomId, async () => {
|
|
457
|
+
await this._payloadStore.room?.delete(loadPayload.roomId);
|
|
458
|
+
await this._payloadStore.roomMember?.delete(loadPayload.roomId);
|
|
459
|
+
});
|
|
460
|
+
if (!this.isEventEpochCurrent(epoch)) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
this.emit('room-member-load', loadPayload);
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
286
466
|
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_MESSAGE:
|
|
287
467
|
this.emit('message', JSON.parse(payload));
|
|
288
468
|
break;
|
|
@@ -355,6 +535,9 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
355
535
|
// Huan(202003): in default, the `type` type should be `never`, please check.
|
|
356
536
|
this.log.error(`eventType ${type} unsupported! data: ${payload}`);
|
|
357
537
|
}
|
|
538
|
+
if (seq && this.isEventEpochCurrent(epoch) && !config_js_1.envVars.WECHATY_PUPPET_SERVICE_DISABLE_EVENT_CACHE()) {
|
|
539
|
+
await this.commitEventCheckpoint(seq, timestamp, epoch);
|
|
540
|
+
}
|
|
358
541
|
}
|
|
359
542
|
async logout(reason) {
|
|
360
543
|
this.log.verbose('PuppetService', 'logout(%s)', reason ? `"${reason}"` : '');
|
|
@@ -410,8 +593,14 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
410
593
|
[PUPPET.types.Dirty.Friendship]: async (_) => { },
|
|
411
594
|
[PUPPET.types.Dirty.Message]: async (_) => { },
|
|
412
595
|
[PUPPET.types.Dirty.Post]: async (_) => { },
|
|
413
|
-
[PUPPET.types.Dirty.Room]: async (id) =>
|
|
414
|
-
|
|
596
|
+
[PUPPET.types.Dirty.Room]: async (id) => {
|
|
597
|
+
this.roomCache.invalidate(id);
|
|
598
|
+
return this.roomCache.run(id, async () => this._payloadStore.room?.delete(id));
|
|
599
|
+
},
|
|
600
|
+
[PUPPET.types.Dirty.RoomMember]: async (id) => {
|
|
601
|
+
this.roomCache.invalidate(id);
|
|
602
|
+
return this.roomCache.run(id, async () => this._payloadStore.roomMember?.delete(id));
|
|
603
|
+
},
|
|
415
604
|
[PUPPET.types.Dirty.Tag]: async (id) => this._payloadStore.tag?.delete(id),
|
|
416
605
|
[PUPPET.types.Dirty.TagGroup]: async (id) => this._payloadStore.tagGroup?.delete(id),
|
|
417
606
|
[PUPPET.types.Dirty.Unspecified]: async (id) => { throw new Error('Unspecified type with id: ' + id); },
|
|
@@ -1580,8 +1769,9 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
1580
1769
|
*/
|
|
1581
1770
|
async roomRawPayload(id) {
|
|
1582
1771
|
this.log.verbose('PuppetService', 'roomRawPayload(%s)', id);
|
|
1583
|
-
const
|
|
1584
|
-
|
|
1772
|
+
const generation = this.roomCache.generation(id);
|
|
1773
|
+
const cachedPayload = await this.roomCache.run(id, async () => this._payloadStore.room?.get(id));
|
|
1774
|
+
if (cachedPayload && generation === this.roomCache.generation(id)) {
|
|
1585
1775
|
this.log.silly('PuppetService', 'roomRawPayload(%s) cache HIT', id);
|
|
1586
1776
|
return cachedPayload;
|
|
1587
1777
|
}
|
|
@@ -1589,26 +1779,52 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
1589
1779
|
request.setId(id);
|
|
1590
1780
|
const response = await util_1.default.promisify(this.grpcManager.client.roomPayload
|
|
1591
1781
|
.bind(this.grpcManager.client))(request);
|
|
1592
|
-
const payload =
|
|
1593
|
-
|
|
1594
|
-
avatar: response.getAvatar(),
|
|
1595
|
-
handle: response.getHandle(),
|
|
1596
|
-
id: response.getId(),
|
|
1597
|
-
memberIdList: response.getMemberIdsList(),
|
|
1598
|
-
ownerId: response.getOwnerId(),
|
|
1599
|
-
topic: response.getTopic(),
|
|
1600
|
-
additionalInfo: response.getAdditionalInfo(),
|
|
1601
|
-
remark: response.getRoomRemark(),
|
|
1602
|
-
external: response.getExternal(),
|
|
1603
|
-
};
|
|
1604
|
-
const createTime = response.getCreateTime();
|
|
1605
|
-
if (createTime) {
|
|
1606
|
-
payload.createTime = (0, timestamp_js_1.millisecondsFromTimestamp)(createTime);
|
|
1607
|
-
}
|
|
1608
|
-
await this._payloadStore.room?.set(id, payload);
|
|
1782
|
+
const payload = (0, pb_payload_helper_js_1.roomPbToPayload)(response);
|
|
1783
|
+
await this.roomCache.commit(id, generation, async () => this._payloadStore.room?.set(id, payload));
|
|
1609
1784
|
this.log.silly('PuppetService', 'roomRawPayload(%s) cache SET', id);
|
|
1610
1785
|
return payload;
|
|
1611
1786
|
}
|
|
1787
|
+
async roomMemberSync(roomId, options) {
|
|
1788
|
+
if (!roomId) {
|
|
1789
|
+
throw new Error('roomId is required');
|
|
1790
|
+
}
|
|
1791
|
+
const request = new wechaty_grpc_1.puppet.RoomMemberSyncRequest();
|
|
1792
|
+
request.setId(roomId);
|
|
1793
|
+
if (options?.force !== undefined) {
|
|
1794
|
+
request.setForce(options.force);
|
|
1795
|
+
}
|
|
1796
|
+
const response = await util_1.default.promisify(this.grpcManager.client.roomMemberSync.bind(this.grpcManager.client))(request);
|
|
1797
|
+
return (0, pb_payload_helper_js_1.roomMemberLoadStatePbToPayload)(response, roomId);
|
|
1798
|
+
}
|
|
1799
|
+
async roomMemberLoadState(roomId) {
|
|
1800
|
+
if (!roomId) {
|
|
1801
|
+
throw new Error('roomId is required');
|
|
1802
|
+
}
|
|
1803
|
+
const request = new wechaty_grpc_1.puppet.RoomMemberLoadStateRequest();
|
|
1804
|
+
request.setId(roomId);
|
|
1805
|
+
const response = await util_1.default.promisify(this.grpcManager.client.roomMemberLoadState.bind(this.grpcManager.client))(request);
|
|
1806
|
+
return (0, pb_payload_helper_js_1.roomMemberLoadStatePbToPayload)(response, roomId);
|
|
1807
|
+
}
|
|
1808
|
+
async roomMemberSnapshot(roomId, revision, options) {
|
|
1809
|
+
if (!roomId) {
|
|
1810
|
+
throw new Error('roomId is required');
|
|
1811
|
+
}
|
|
1812
|
+
(0, pb_payload_helper_js_1.validateRoomMemberRevision)(revision);
|
|
1813
|
+
const request = new wechaty_grpc_1.puppet.RoomMemberSnapshotRequest();
|
|
1814
|
+
request.setId(roomId);
|
|
1815
|
+
request.setRevision(revision);
|
|
1816
|
+
if (options?.pageToken !== undefined) {
|
|
1817
|
+
request.setPageToken(options.pageToken);
|
|
1818
|
+
}
|
|
1819
|
+
if (options?.pageSize !== undefined) {
|
|
1820
|
+
if (!Number.isInteger(options.pageSize) || options.pageSize < 0 || options.pageSize > 500) {
|
|
1821
|
+
throw new Error('pageSize must be an integer between 0 and 500');
|
|
1822
|
+
}
|
|
1823
|
+
request.setPageSize(options.pageSize);
|
|
1824
|
+
}
|
|
1825
|
+
const response = await util_1.default.promisify(this.grpcManager.client.roomMemberSnapshot.bind(this.grpcManager.client))(request);
|
|
1826
|
+
return (0, pb_payload_helper_js_1.roomMemberSnapshotPbToPayload)(response, roomId, revision);
|
|
1827
|
+
}
|
|
1612
1828
|
async roomRawPayloadParser(payload) {
|
|
1613
1829
|
// this.log.silly('PuppetService', 'roomRawPayloadParser({id:%s})', payload.id)
|
|
1614
1830
|
// passthrough
|
|
@@ -1618,10 +1834,11 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
1618
1834
|
this.log.verbose('PuppetService', 'batchRoomRawPayload(%s)', roomIdList);
|
|
1619
1835
|
const result = new Map();
|
|
1620
1836
|
const roomIdSet = new Set(roomIdList);
|
|
1837
|
+
const generations = new Map(Array.from(roomIdSet, id => [id, this.roomCache.generation(id)]));
|
|
1621
1838
|
const needGetSet = new Set();
|
|
1622
1839
|
for (const roomId of roomIdSet) {
|
|
1623
|
-
const cachedRoomPayload = await this._payloadStore.room?.get(roomId);
|
|
1624
|
-
if (cachedRoomPayload) {
|
|
1840
|
+
const cachedRoomPayload = await this.roomCache.run(roomId, async () => this._payloadStore.room?.get(roomId));
|
|
1841
|
+
if (cachedRoomPayload && generations.get(roomId) === this.roomCache.generation(roomId)) {
|
|
1625
1842
|
result.set(roomId, cachedRoomPayload);
|
|
1626
1843
|
}
|
|
1627
1844
|
else {
|
|
@@ -1637,27 +1854,18 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
1637
1854
|
const payloads = response.getRoomPayloadsList();
|
|
1638
1855
|
for (const payload of payloads) {
|
|
1639
1856
|
const roomId = payload.getId();
|
|
1640
|
-
const puppetPayload =
|
|
1641
|
-
adminIdList: payload.getAdminIdsList(),
|
|
1642
|
-
avatar: payload.getAvatar(),
|
|
1643
|
-
handle: payload.getHandle(),
|
|
1644
|
-
id: payload.getId(),
|
|
1645
|
-
memberIdList: payload.getMemberIdsList(),
|
|
1646
|
-
ownerId: payload.getOwnerId(),
|
|
1647
|
-
topic: payload.getTopic(),
|
|
1648
|
-
additionalInfo: payload.getAdditionalInfo(),
|
|
1649
|
-
remark: payload.getRoomRemark(),
|
|
1650
|
-
external: payload.getExternal(),
|
|
1651
|
-
};
|
|
1652
|
-
const createTime = payload.getCreateTime();
|
|
1653
|
-
if (createTime) {
|
|
1654
|
-
puppetPayload.createTime = (0, timestamp_js_1.millisecondsFromTimestamp)(createTime);
|
|
1655
|
-
}
|
|
1857
|
+
const puppetPayload = (0, pb_payload_helper_js_1.roomPbToPayload)(payload);
|
|
1656
1858
|
result.set(roomId, puppetPayload);
|
|
1657
|
-
|
|
1859
|
+
const generation = generations.get(roomId);
|
|
1860
|
+
if (generation !== undefined) {
|
|
1861
|
+
await this.roomCache.commit(roomId, generation, async () => this._payloadStore.room?.set(roomId, puppetPayload));
|
|
1862
|
+
}
|
|
1658
1863
|
}
|
|
1659
1864
|
}
|
|
1660
1865
|
catch (e) {
|
|
1866
|
+
if (e instanceof room_cache_coordinator_js_1.RoomCacheOperationError) {
|
|
1867
|
+
throw e;
|
|
1868
|
+
}
|
|
1661
1869
|
this.log.error('PuppetService', 'batchRoomRawPayload(%s, %s) error: %s, use one by one method', roomIdList, needGetSet, e);
|
|
1662
1870
|
let fallbackSuccessCount = 0;
|
|
1663
1871
|
for (const roomId of needGetSet) {
|
|
@@ -1843,9 +2051,10 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
1843
2051
|
}
|
|
1844
2052
|
async roomMemberRawPayload(roomId, contactId) {
|
|
1845
2053
|
this.log.verbose('PuppetService', 'roomMemberRawPayload(%s, %s)', roomId, contactId);
|
|
1846
|
-
const
|
|
2054
|
+
const generation = this.roomCache.generation(roomId);
|
|
2055
|
+
const cachedPayload = await this.roomCache.run(roomId, async () => this._payloadStore.roomMember?.get(roomId));
|
|
1847
2056
|
const cachedRoomMemberPayload = cachedPayload && cachedPayload[contactId];
|
|
1848
|
-
if (cachedRoomMemberPayload) {
|
|
2057
|
+
if (cachedRoomMemberPayload && generation === this.roomCache.generation(roomId)) {
|
|
1849
2058
|
this.log.silly('PuppetService', 'roomMemberRawPayload(%s, %s) cache HIT', roomId, contactId);
|
|
1850
2059
|
return cachedRoomMemberPayload;
|
|
1851
2060
|
}
|
|
@@ -1864,9 +2073,9 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
1864
2073
|
joinScene: response.getJoinScene(),
|
|
1865
2074
|
joinTime: response.getJoinTime(),
|
|
1866
2075
|
};
|
|
1867
|
-
await this.
|
|
1868
|
-
|
|
1869
|
-
[contactId]: payload
|
|
2076
|
+
await this.roomCache.commit(roomId, generation, async () => {
|
|
2077
|
+
const current = await this._payloadStore.roomMember?.get(roomId);
|
|
2078
|
+
await this._payloadStore.roomMember?.set(roomId, { ...current, [contactId]: payload });
|
|
1870
2079
|
});
|
|
1871
2080
|
this.log.silly('PuppetService', 'roomMemberRawPayload(%s, %s) cache SET', roomId, contactId);
|
|
1872
2081
|
return payload;
|
|
@@ -1878,10 +2087,12 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
1878
2087
|
}
|
|
1879
2088
|
async batchRoomMemberRawPayload(roomId, contactIdList) {
|
|
1880
2089
|
this.log.verbose('PuppetService', 'batchRoomMemberRawPayload(%s, %s)', roomId, contactIdList);
|
|
2090
|
+
const generation = this.roomCache.generation(roomId);
|
|
1881
2091
|
const result = new Map();
|
|
1882
2092
|
const contactIdSet = new Set(contactIdList);
|
|
1883
2093
|
let needGetSet = new Set();
|
|
1884
|
-
const
|
|
2094
|
+
const cached = await this.roomCache.run(roomId, async () => this._payloadStore.roomMember?.get(roomId));
|
|
2095
|
+
const cachedPayload = generation === this.roomCache.generation(roomId) ? cached || {} : {};
|
|
1885
2096
|
if (Object.keys(cachedPayload).length > 0) {
|
|
1886
2097
|
for (const contactId of contactIdSet) {
|
|
1887
2098
|
const cachedRoomMemberPayload = cachedPayload[contactId];
|
|
@@ -1904,15 +2115,22 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
1904
2115
|
const response = await util_1.default.promisify(this.grpcManager.client.batchRoomMemberPayload
|
|
1905
2116
|
.bind(this.grpcManager.client))(request);
|
|
1906
2117
|
const payloads = response.getMemberPayloadsList();
|
|
2118
|
+
const fetched = {};
|
|
1907
2119
|
for (const payload of payloads) {
|
|
1908
2120
|
const contactId = payload.getId();
|
|
1909
2121
|
const puppetPayload = (0, pb_payload_helper_js_1.roomMemberPbToPayload)(payload);
|
|
1910
2122
|
result.set(contactId, puppetPayload);
|
|
1911
|
-
|
|
2123
|
+
fetched[contactId] = puppetPayload;
|
|
1912
2124
|
}
|
|
1913
|
-
await this.
|
|
2125
|
+
await this.roomCache.commit(roomId, generation, async () => {
|
|
2126
|
+
const current = await this._payloadStore.roomMember?.get(roomId);
|
|
2127
|
+
await this._payloadStore.roomMember?.set(roomId, { ...current, ...fetched });
|
|
2128
|
+
});
|
|
1914
2129
|
}
|
|
1915
2130
|
catch (e) {
|
|
2131
|
+
if (e instanceof room_cache_coordinator_js_1.RoomCacheOperationError) {
|
|
2132
|
+
throw e;
|
|
2133
|
+
}
|
|
1916
2134
|
this.log.error('PuppetService', 'batchRoomMemberRawPayload(%s, %s) error: %s, use one by one method', roomId, needGetSet, e);
|
|
1917
2135
|
for (const contactId of needGetSet) {
|
|
1918
2136
|
const payload = await this.roomMemberRawPayload(roomId, contactId);
|
|
@@ -2654,23 +2872,40 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
2654
2872
|
waitingForReady = false;
|
|
2655
2873
|
reconnectIndicator;
|
|
2656
2874
|
async reset() {
|
|
2657
|
-
if (!this._grpcManager) {
|
|
2658
|
-
this.log.warn('PuppetService', 'grpc manager not constructed, perform regular reset');
|
|
2659
|
-
return super.reset();
|
|
2660
|
-
}
|
|
2661
|
-
if (!this.isLoggedIn) {
|
|
2662
|
-
this.log.warn('PuppetService', 'puppet not logged in, perform regular reset');
|
|
2663
|
-
return super.reset();
|
|
2664
|
-
}
|
|
2665
2875
|
if (this.reconnectIndicator.value()) {
|
|
2666
2876
|
this.log.warn('PuppetService', 'already trying to reconnect, pass this one');
|
|
2667
2877
|
return;
|
|
2668
2878
|
}
|
|
2669
2879
|
this.reconnectIndicator.value(true);
|
|
2670
|
-
this.
|
|
2671
|
-
const
|
|
2880
|
+
this.suspendEventProcessing();
|
|
2881
|
+
const epoch = this.eventEpoch;
|
|
2882
|
+
const manager = this._grpcManager;
|
|
2883
|
+
try {
|
|
2884
|
+
await this.checkpointQueue;
|
|
2885
|
+
if (epoch !== this.eventEpoch) {
|
|
2886
|
+
return;
|
|
2887
|
+
}
|
|
2888
|
+
if (!manager || !this.isLoggedIn) {
|
|
2889
|
+
this.log.warn('PuppetService', 'grpc manager unavailable or puppet logged out, perform regular reset');
|
|
2890
|
+
return await super.reset();
|
|
2891
|
+
}
|
|
2892
|
+
await this.resetEventStream(manager, epoch);
|
|
2893
|
+
}
|
|
2894
|
+
finally {
|
|
2895
|
+
this.reconnectIndicator.value(false);
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
async resetEventStream(manager, epoch) {
|
|
2899
|
+
manager.stopStream();
|
|
2900
|
+
const { lastEventSeq, accountId } = await this.eventResumePosition(epoch);
|
|
2901
|
+
if (epoch !== this.eventEpoch || manager !== this._grpcManager) {
|
|
2902
|
+
return;
|
|
2903
|
+
}
|
|
2672
2904
|
const onLoginResolve = (resolve) => {
|
|
2673
2905
|
const onLogin = (event) => {
|
|
2906
|
+
if (!this.ownsEventWorker(manager, epoch)) {
|
|
2907
|
+
return;
|
|
2908
|
+
}
|
|
2674
2909
|
const type = event.getType();
|
|
2675
2910
|
const payload = event.getPayload();
|
|
2676
2911
|
if (this.waitingForLogin && type === wechaty_grpc_1.puppet.EventType.EVENT_TYPE_LOGIN) {
|
|
@@ -2686,6 +2921,9 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
2686
2921
|
};
|
|
2687
2922
|
const onReadyResolve = (resolve) => {
|
|
2688
2923
|
const onReady = (event) => {
|
|
2924
|
+
if (!this.ownsEventWorker(manager, epoch)) {
|
|
2925
|
+
return;
|
|
2926
|
+
}
|
|
2689
2927
|
const type = event.getType();
|
|
2690
2928
|
if (this.waitingForReady && type === wechaty_grpc_1.puppet.EventType.EVENT_TYPE_READY) {
|
|
2691
2929
|
this.waitingForReady = false;
|
|
@@ -2694,60 +2932,85 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
2694
2932
|
};
|
|
2695
2933
|
return onReady;
|
|
2696
2934
|
};
|
|
2697
|
-
|
|
2698
|
-
let onReady;
|
|
2935
|
+
const removeListeners = [];
|
|
2699
2936
|
const loginFuture = new Promise(resolve => {
|
|
2700
|
-
onLogin = onLoginResolve(resolve);
|
|
2701
|
-
|
|
2937
|
+
const onLogin = onLoginResolve(resolve);
|
|
2938
|
+
manager.on('data', onLogin);
|
|
2939
|
+
removeListeners.push(() => { manager.off('data', onLogin); });
|
|
2702
2940
|
});
|
|
2703
2941
|
const readyFuture = new Promise(resolve => {
|
|
2704
|
-
onReady = onReadyResolve(resolve);
|
|
2705
|
-
|
|
2942
|
+
const onReady = onReadyResolve(resolve);
|
|
2943
|
+
manager.on('data', onReady);
|
|
2944
|
+
removeListeners.push(() => { manager.off('data', onReady); });
|
|
2706
2945
|
});
|
|
2707
2946
|
const startTime = Date.now();
|
|
2708
2947
|
const timeoutMilliseconds = this.timeoutMilliseconds / 10; // 2 min default, 4 min xiaoju-bot
|
|
2709
|
-
|
|
2948
|
+
this.waitingForLogin = true;
|
|
2949
|
+
this.waitingForReady = true;
|
|
2950
|
+
this.eventsBlocked = false;
|
|
2951
|
+
try {
|
|
2952
|
+
while (true) {
|
|
2953
|
+
try {
|
|
2954
|
+
if (!this.ownsEventWorker(manager, epoch)) {
|
|
2955
|
+
return;
|
|
2956
|
+
}
|
|
2957
|
+
await (0, gerror_1.timeoutPromise)(manager.startStream(lastEventSeq, accountId), 30 * 1000);
|
|
2958
|
+
if (!this.ownsEventWorker(manager, epoch)) {
|
|
2959
|
+
return;
|
|
2960
|
+
}
|
|
2961
|
+
break;
|
|
2962
|
+
}
|
|
2963
|
+
catch (e) {
|
|
2964
|
+
if (!this.ownsEventWorker(manager, epoch)) {
|
|
2965
|
+
return;
|
|
2966
|
+
}
|
|
2967
|
+
if (Date.now() - startTime < timeoutMilliseconds) {
|
|
2968
|
+
this.log.warn('failed to start stream, will try again in 15 seconds');
|
|
2969
|
+
await new Promise(resolve => {
|
|
2970
|
+
setTimeout(resolve, 5000);
|
|
2971
|
+
});
|
|
2972
|
+
}
|
|
2973
|
+
else {
|
|
2974
|
+
this.log.warn('failed to start stream and reaches timeout, will perform regular reset');
|
|
2975
|
+
return super.reset();
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2710
2979
|
try {
|
|
2711
|
-
await (0, gerror_1.timeoutPromise)(
|
|
2712
|
-
|
|
2980
|
+
await (0, gerror_1.timeoutPromise)(loginFuture, ResetLoginTimeout)
|
|
2981
|
+
.finally(() => {
|
|
2982
|
+
if (epoch === this.eventEpoch) {
|
|
2983
|
+
this.waitingForLogin = false;
|
|
2984
|
+
}
|
|
2985
|
+
});
|
|
2713
2986
|
}
|
|
2714
2987
|
catch (e) {
|
|
2715
|
-
if (
|
|
2716
|
-
|
|
2717
|
-
await new Promise(resolve => {
|
|
2718
|
-
setTimeout(resolve, 5000);
|
|
2719
|
-
});
|
|
2720
|
-
}
|
|
2721
|
-
else {
|
|
2722
|
-
this.log.warn('failed to start stream and reaches timeout, will perform regular reset');
|
|
2723
|
-
this.reconnectIndicator.value(false);
|
|
2724
|
-
return super.reset();
|
|
2988
|
+
if (!this.ownsEventWorker(manager, epoch)) {
|
|
2989
|
+
return;
|
|
2725
2990
|
}
|
|
2991
|
+
this.log.warn('PuppetService', 'waiting for event reset login error, will perform regular reset');
|
|
2992
|
+
return super.reset();
|
|
2993
|
+
}
|
|
2994
|
+
try {
|
|
2995
|
+
await (0, gerror_1.timeoutPromise)(readyFuture, ResetReadyTimeout)
|
|
2996
|
+
.finally(() => {
|
|
2997
|
+
if (epoch === this.eventEpoch) {
|
|
2998
|
+
this.waitingForReady = false;
|
|
2999
|
+
}
|
|
3000
|
+
});
|
|
3001
|
+
}
|
|
3002
|
+
catch (e) {
|
|
3003
|
+
this.log.warn('PuppetService', 'waiting for event reset ready error, will do nothing');
|
|
2726
3004
|
}
|
|
2727
3005
|
}
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
3006
|
+
finally {
|
|
3007
|
+
for (const removeListener of removeListeners) {
|
|
3008
|
+
removeListener();
|
|
3009
|
+
}
|
|
3010
|
+
if (epoch === this.eventEpoch) {
|
|
2733
3011
|
this.waitingForLogin = false;
|
|
2734
|
-
this.reconnectIndicator.value(false);
|
|
2735
|
-
this.grpcManager.off('data', onLogin);
|
|
2736
|
-
});
|
|
2737
|
-
}
|
|
2738
|
-
catch (e) {
|
|
2739
|
-
this.log.warn('PuppetService', 'waiting for event reset login error, will perform regular reset');
|
|
2740
|
-
return super.reset();
|
|
2741
|
-
}
|
|
2742
|
-
try {
|
|
2743
|
-
await (0, gerror_1.timeoutPromise)(readyFuture, ResetReadyTimeout)
|
|
2744
|
-
.finally(() => {
|
|
2745
3012
|
this.waitingForReady = false;
|
|
2746
|
-
|
|
2747
|
-
});
|
|
2748
|
-
}
|
|
2749
|
-
catch (e) {
|
|
2750
|
-
this.log.warn('PuppetService', 'waiting for event reset ready error, will do nothing');
|
|
3013
|
+
}
|
|
2751
3014
|
}
|
|
2752
3015
|
}
|
|
2753
3016
|
async getMiscellaneousStoreData() {
|
|
@@ -2771,27 +3034,29 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
2771
3034
|
accountId,
|
|
2772
3035
|
};
|
|
2773
3036
|
}
|
|
2774
|
-
async setMiscellaneousStoreData(data) {
|
|
3037
|
+
async setMiscellaneousStoreData(data, epoch) {
|
|
2775
3038
|
if (config_js_1.envVars.WECHATY_PUPPET_SERVICE_DISABLE_EVENT_CACHE()) {
|
|
2776
3039
|
return;
|
|
2777
3040
|
}
|
|
2778
|
-
|
|
2779
|
-
|
|
3041
|
+
const changes = new Map();
|
|
3042
|
+
if (data.lastEventTimestamp !== undefined) {
|
|
3043
|
+
changes.set('lastEventTimestamp', data.lastEventTimestamp);
|
|
2780
3044
|
}
|
|
2781
|
-
if (
|
|
2782
|
-
|
|
3045
|
+
if (data.accountId !== undefined) {
|
|
3046
|
+
changes.set('accountId', data.accountId);
|
|
2783
3047
|
}
|
|
2784
|
-
if (
|
|
2785
|
-
|
|
3048
|
+
if (data.lastEventSeq !== undefined) {
|
|
3049
|
+
changes.set('lastEventSeq', data.lastEventSeq);
|
|
2786
3050
|
}
|
|
3051
|
+
await this.withEventCheckpoint(async () => this.writeEventMetadata(changes, epoch));
|
|
2787
3052
|
}
|
|
2788
|
-
async resetMiscellaneousStoreData() {
|
|
3053
|
+
async resetMiscellaneousStoreData(epoch) {
|
|
2789
3054
|
if (config_js_1.envVars.WECHATY_PUPPET_SERVICE_DISABLE_EVENT_CACHE()) {
|
|
2790
3055
|
return;
|
|
2791
3056
|
}
|
|
2792
|
-
await this.
|
|
2793
|
-
|
|
2794
|
-
|
|
3057
|
+
await this.withEventCheckpoint(async () => this.writeEventMetadata(new Map([
|
|
3058
|
+
['lastEventSeq', undefined], ['lastEventTimestamp', undefined], ['accountId', undefined],
|
|
3059
|
+
]), epoch));
|
|
2795
3060
|
}
|
|
2796
3061
|
}
|
|
2797
3062
|
exports.PuppetService = PuppetService;
|