@hatchet-dev/typescript-sdk 1.34.0 → 1.34.1
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/clients/dispatcher/action-listener.d.ts +1 -0
- package/clients/dispatcher/action-listener.js +10 -5
- package/clients/listeners/durable-listener/durable-listener-client.d.ts +11 -1
- package/clients/listeners/durable-listener/durable-listener-client.js +113 -43
- package/package.json +1 -1
- package/v1/client/worker/worker-internal.d.ts +2 -0
- package/v1/client/worker/worker-internal.js +36 -11
- package/version.d.ts +1 -1
- package/version.js +1 -1
|
@@ -28,5 +28,6 @@ export declare class ActionListener {
|
|
|
28
28
|
getListenStrategy(): Promise<ListenStrategy>;
|
|
29
29
|
incrementRetries(): Promise<void>;
|
|
30
30
|
getListenClient(): Promise<AsyncIterable<AssignedAction>>;
|
|
31
|
+
stopStream(): void;
|
|
31
32
|
unregister(): Promise<import("../../protoc/dispatcher").WorkerUnsubscribeResponse>;
|
|
32
33
|
}
|
|
@@ -225,14 +225,19 @@ class ActionListener {
|
|
|
225
225
|
}
|
|
226
226
|
});
|
|
227
227
|
}
|
|
228
|
+
// Leaves the heartbeat running: tasks that are already in flight still need
|
|
229
|
+
// the engine to see this worker as alive until they finish.
|
|
230
|
+
stopStream() {
|
|
231
|
+
this.done = true;
|
|
232
|
+
// Abort the gRPC stream to immediately cancel the generator
|
|
233
|
+
if (this.abortController) {
|
|
234
|
+
this.abortController.abort('Worker stopping');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
228
237
|
unregister() {
|
|
229
238
|
return __awaiter(this, void 0, void 0, function* () {
|
|
230
|
-
this.
|
|
239
|
+
this.stopStream();
|
|
231
240
|
this.heartbeat.stop();
|
|
232
|
-
// Abort the gRPC stream to immediately cancel the generator
|
|
233
|
-
if (this.abortController) {
|
|
234
|
-
this.abortController.abort('Worker stopping');
|
|
235
|
-
}
|
|
236
241
|
try {
|
|
237
242
|
return yield this.client.unsubscribe({
|
|
238
243
|
workerId: this.workerId,
|
|
@@ -18,6 +18,9 @@ export declare class DurableListenerClient {
|
|
|
18
18
|
private _pendingCallbacks;
|
|
19
19
|
private _orderedCompletions;
|
|
20
20
|
private _pendingEvictionAcks;
|
|
21
|
+
private _newlyWaitingKeys;
|
|
22
|
+
private _waitingSince;
|
|
23
|
+
private _workerStatusSendScheduled;
|
|
21
24
|
private _receiveAbort;
|
|
22
25
|
private _statusInterval;
|
|
23
26
|
private _startLock;
|
|
@@ -34,13 +37,20 @@ export declare class DurableListenerClient {
|
|
|
34
37
|
private _requestIterator;
|
|
35
38
|
private _enqueueRequest;
|
|
36
39
|
private _startStatusPolling;
|
|
37
|
-
private
|
|
40
|
+
private _registerWaitingKey;
|
|
41
|
+
private _scheduleWorkerStatusSend;
|
|
42
|
+
private _enqueueWorkerStatusForNewlyWaitingKeys;
|
|
43
|
+
private _enqueueWorkerStatusForLongPendingWaiters;
|
|
44
|
+
private _enqueueFullWorkerStatus;
|
|
45
|
+
private _enqueueWorkerStatusFor;
|
|
38
46
|
private _failPendingAcks;
|
|
39
47
|
private _failAllPending;
|
|
40
48
|
private _handleResponse;
|
|
41
49
|
sendEvent(durableTaskExternalId: string, invocationCount: number, event: RunChildrenEvent): Promise<DurableTaskEventRunAck>;
|
|
42
50
|
sendEvent(durableTaskExternalId: string, invocationCount: number, event: WaitForEvent): Promise<DurableTaskEventWaitForAck>;
|
|
43
51
|
sendEvent(durableTaskExternalId: string, invocationCount: number, event: MemoEvent): Promise<DurableTaskEventMemoAck>;
|
|
52
|
+
private _sendRequestAndAwaitAck;
|
|
53
|
+
private _sendRunChildrenEvent;
|
|
44
54
|
private _drainsInProgress;
|
|
45
55
|
private _drainRerunRequests;
|
|
46
56
|
private _drainOrderedCompletions;
|
|
@@ -94,7 +94,10 @@ class TTLMap {
|
|
|
94
94
|
}
|
|
95
95
|
const DEFAULT_RECONNECT_INTERVAL = 3000;
|
|
96
96
|
const EVICTION_ACK_TIMEOUT_MS = 30000;
|
|
97
|
-
const
|
|
97
|
+
const WORKER_STATUS_RESEND_INTERVAL_MS = 5000;
|
|
98
|
+
const WORKER_STATUS_RESEND_MIN_PENDING_MS = 2000;
|
|
99
|
+
const WORKER_STATUS_MAX_ENTRIES_PER_REQUEST = 10000;
|
|
100
|
+
const RUN_CHILDREN_MAX_CHILDREN_PER_REQUEST = 100;
|
|
98
101
|
function eventLogEntryResultFromProto(proto) {
|
|
99
102
|
var _a, _b, _c, _d;
|
|
100
103
|
let payload;
|
|
@@ -109,6 +112,15 @@ function eventLogEntryResultFromProto(proto) {
|
|
|
109
112
|
errorMessage: proto.errorMessage,
|
|
110
113
|
};
|
|
111
114
|
}
|
|
115
|
+
function awaitedCompletedEntryFromCallbackKey(key) {
|
|
116
|
+
const [durableTaskExternalId, invocationCount, branchId, nodeId] = key.split(':');
|
|
117
|
+
return {
|
|
118
|
+
durableTaskExternalId,
|
|
119
|
+
invocationCount: parseInt(invocationCount, 10),
|
|
120
|
+
branchId: parseInt(branchId, 10),
|
|
121
|
+
nodeId: parseInt(nodeId, 10),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
112
124
|
function ackKey(taskExtId, invocationCount) {
|
|
113
125
|
return `${taskExtId}:${invocationCount}`;
|
|
114
126
|
}
|
|
@@ -142,6 +154,9 @@ class DurableListenerClient {
|
|
|
142
154
|
// without consuming everything; the server stall-evicts long before.
|
|
143
155
|
this._orderedCompletions = new TTLMap(300000);
|
|
144
156
|
this._pendingEvictionAcks = new Map();
|
|
157
|
+
this._newlyWaitingKeys = new Set();
|
|
158
|
+
this._waitingSince = new Map();
|
|
159
|
+
this._workerStatusSendScheduled = false;
|
|
145
160
|
this._consecutiveFailures = 0;
|
|
146
161
|
this._drainsInProgress = new Set();
|
|
147
162
|
this._drainRerunRequests = new Set();
|
|
@@ -205,7 +220,7 @@ class DurableListenerClient {
|
|
|
205
220
|
this._enqueueRequest({
|
|
206
221
|
registerWorker: { workerId: this._workerId },
|
|
207
222
|
});
|
|
208
|
-
this.
|
|
223
|
+
this._enqueueFullWorkerStatus();
|
|
209
224
|
void this._streamLoop();
|
|
210
225
|
this.logger.info('durable event listener connected');
|
|
211
226
|
});
|
|
@@ -300,28 +315,57 @@ class DurableListenerClient {
|
|
|
300
315
|
clearInterval(this._statusInterval);
|
|
301
316
|
}
|
|
302
317
|
this._statusInterval = setInterval(() => {
|
|
303
|
-
this.
|
|
304
|
-
},
|
|
318
|
+
this._enqueueWorkerStatusForLongPendingWaiters();
|
|
319
|
+
}, WORKER_STATUS_RESEND_INTERVAL_MS);
|
|
305
320
|
}
|
|
306
|
-
|
|
307
|
-
|
|
321
|
+
_registerWaitingKey(key) {
|
|
322
|
+
this._waitingSince.set(key, Date.now());
|
|
323
|
+
this._newlyWaitingKeys.add(key);
|
|
324
|
+
}
|
|
325
|
+
// Waiters registered in the same turn of the event loop share one request,
|
|
326
|
+
// instead of each sending its own.
|
|
327
|
+
_scheduleWorkerStatusSend() {
|
|
328
|
+
if (this._workerStatusSendScheduled)
|
|
308
329
|
return;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
330
|
+
this._workerStatusSendScheduled = true;
|
|
331
|
+
setImmediate(() => this._enqueueWorkerStatusForNewlyWaitingKeys());
|
|
332
|
+
}
|
|
333
|
+
_enqueueWorkerStatusForNewlyWaitingKeys() {
|
|
334
|
+
this._workerStatusSendScheduled = false;
|
|
335
|
+
const keys = [...this._newlyWaitingKeys].filter((key) => this._pendingCallbacks.has(key));
|
|
336
|
+
this._newlyWaitingKeys.clear();
|
|
337
|
+
this._enqueueWorkerStatusFor(keys);
|
|
338
|
+
}
|
|
339
|
+
_enqueueWorkerStatusForLongPendingWaiters() {
|
|
340
|
+
const registeredBefore = Date.now() - WORKER_STATUS_RESEND_MIN_PENDING_MS;
|
|
341
|
+
const keys = [];
|
|
342
|
+
for (const [key, waitingSince] of this._waitingSince) {
|
|
343
|
+
if (!this._pendingCallbacks.has(key)) {
|
|
344
|
+
this._waitingSince.delete(key);
|
|
345
|
+
}
|
|
346
|
+
else if (waitingSince <= registeredBefore) {
|
|
347
|
+
keys.push(key);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
this._enqueueWorkerStatusFor(keys);
|
|
351
|
+
}
|
|
352
|
+
_enqueueFullWorkerStatus() {
|
|
353
|
+
this._newlyWaitingKeys.clear();
|
|
354
|
+
this._enqueueWorkerStatusFor([...this._pendingCallbacks.keys()]);
|
|
355
|
+
}
|
|
356
|
+
_enqueueWorkerStatusFor(keys, maxEntriesPerRequest = WORKER_STATUS_MAX_ENTRIES_PER_REQUEST) {
|
|
357
|
+
if (!this._workerId)
|
|
358
|
+
return;
|
|
359
|
+
for (let start = 0; start < keys.length; start += maxEntriesPerRequest) {
|
|
360
|
+
this._enqueueRequest({
|
|
361
|
+
workerStatus: {
|
|
362
|
+
workerId: this._workerId,
|
|
363
|
+
waitingEntries: keys
|
|
364
|
+
.slice(start, start + maxEntriesPerRequest)
|
|
365
|
+
.map(awaitedCompletedEntryFromCallbackKey),
|
|
366
|
+
},
|
|
317
367
|
});
|
|
318
368
|
}
|
|
319
|
-
this._enqueueRequest({
|
|
320
|
-
workerStatus: {
|
|
321
|
-
workerId: this._workerId,
|
|
322
|
-
waitingEntries,
|
|
323
|
-
},
|
|
324
|
-
});
|
|
325
369
|
}
|
|
326
370
|
_failPendingAcks(exc) {
|
|
327
371
|
for (const d of this._pendingEventAcks.values()) {
|
|
@@ -406,13 +450,15 @@ class DurableListenerClient {
|
|
|
406
450
|
const orderKey = completionOrderKey((_s = ref === null || ref === void 0 ? void 0 : ref.durableTaskExternalId) !== null && _s !== void 0 ? _s : '', (_t = ref === null || ref === void 0 ? void 0 : ref.invocationCount) !== null && _t !== void 0 ? _t : 0);
|
|
407
451
|
const queue = (_u = this._orderedCompletions.get(orderKey)) !== null && _u !== void 0 ? _u : {
|
|
408
452
|
pending: [],
|
|
453
|
+
pendingKeys: new Set(),
|
|
409
454
|
delivered: new Set(),
|
|
410
455
|
};
|
|
411
456
|
if (!queue.delivered.has(key)) {
|
|
412
457
|
queue.delivered.add(key);
|
|
458
|
+
queue.pendingKeys.add(key);
|
|
413
459
|
queue.pending.push({ key, result });
|
|
414
460
|
}
|
|
415
|
-
else if (queue.
|
|
461
|
+
else if (!queue.pendingKeys.has(key)) {
|
|
416
462
|
// Re-delivery of a completion that already drained (reconnect,
|
|
417
463
|
// worker-status re-send, or a repeated wait on a node deduped by
|
|
418
464
|
// child key). Its satisfied order was released before anything
|
|
@@ -478,20 +524,10 @@ class DurableListenerClient {
|
|
|
478
524
|
}
|
|
479
525
|
sendEvent(durableTaskExternalId, invocationCount, event) {
|
|
480
526
|
return __awaiter(this, void 0, void 0, function* () {
|
|
481
|
-
const key = ackKey(durableTaskExternalId, invocationCount);
|
|
482
|
-
const d = deferred();
|
|
483
|
-
this._pendingEventAcks.set(key, d);
|
|
484
527
|
let request;
|
|
485
528
|
switch (event.kind) {
|
|
486
|
-
case 'runChildren':
|
|
487
|
-
|
|
488
|
-
invocationCount,
|
|
489
|
-
durableTaskExternalId,
|
|
490
|
-
triggerOpts: event.triggerOpts,
|
|
491
|
-
};
|
|
492
|
-
request = { triggerRuns: triggerRunsReq };
|
|
493
|
-
break;
|
|
494
|
-
}
|
|
529
|
+
case 'runChildren':
|
|
530
|
+
return this._sendRunChildrenEvent(durableTaskExternalId, invocationCount, event);
|
|
495
531
|
case 'waitFor': {
|
|
496
532
|
const waitForReq = {
|
|
497
533
|
invocationCount,
|
|
@@ -517,8 +553,33 @@ class DurableListenerClient {
|
|
|
517
553
|
throw new Error(`Unknown durable task send event: ${_}`);
|
|
518
554
|
}
|
|
519
555
|
}
|
|
520
|
-
this.
|
|
521
|
-
|
|
556
|
+
return this._sendRequestAndAwaitAck(durableTaskExternalId, invocationCount, request);
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
_sendRequestAndAwaitAck(durableTaskExternalId, invocationCount, request) {
|
|
560
|
+
const d = deferred();
|
|
561
|
+
this._pendingEventAcks.set(ackKey(durableTaskExternalId, invocationCount), d);
|
|
562
|
+
this._enqueueRequest(request);
|
|
563
|
+
return d.promise;
|
|
564
|
+
}
|
|
565
|
+
_sendRunChildrenEvent(durableTaskExternalId, invocationCount, event) {
|
|
566
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
567
|
+
const runEntries = [];
|
|
568
|
+
for (let start = 0; start < event.triggerOpts.length; start += RUN_CHILDREN_MAX_CHILDREN_PER_REQUEST) {
|
|
569
|
+
const triggerRunsReq = {
|
|
570
|
+
invocationCount,
|
|
571
|
+
durableTaskExternalId,
|
|
572
|
+
triggerOpts: event.triggerOpts.slice(start, start + RUN_CHILDREN_MAX_CHILDREN_PER_REQUEST),
|
|
573
|
+
};
|
|
574
|
+
const ack = yield this._sendRequestAndAwaitAck(durableTaskExternalId, invocationCount, {
|
|
575
|
+
triggerRuns: triggerRunsReq,
|
|
576
|
+
});
|
|
577
|
+
if (ack.ackType !== 'run') {
|
|
578
|
+
throw new Error(`Expected a run ack for a trigger runs request, got ${ack.ackType}`);
|
|
579
|
+
}
|
|
580
|
+
runEntries.push(...ack.runEntries);
|
|
581
|
+
}
|
|
582
|
+
return { ackType: 'run', invocationCount, durableTaskExternalId, runEntries };
|
|
522
583
|
});
|
|
523
584
|
}
|
|
524
585
|
// Hands queued completions to their waiters strictly in delivery order.
|
|
@@ -560,6 +621,7 @@ class DurableListenerClient {
|
|
|
560
621
|
if (!waiter)
|
|
561
622
|
return;
|
|
562
623
|
queue.pending.shift();
|
|
624
|
+
queue.pendingKeys.delete(head.key);
|
|
563
625
|
this._pendingCallbacks.delete(head.key);
|
|
564
626
|
waiter.resolve(head.result);
|
|
565
627
|
released = true;
|
|
@@ -577,6 +639,7 @@ class DurableListenerClient {
|
|
|
577
639
|
const d = deferred();
|
|
578
640
|
d.promise.catch(() => { });
|
|
579
641
|
this._pendingCallbacks.set(key, d);
|
|
642
|
+
this._registerWaitingKey(key);
|
|
580
643
|
this._drainOrderedCompletions(completionOrderKey(durableTaskExternalId, invocationCount));
|
|
581
644
|
}
|
|
582
645
|
waitForCallback(durableTaskExternalId, invocationCount, branchId, nodeId, opts) {
|
|
@@ -594,9 +657,10 @@ class DurableListenerClient {
|
|
|
594
657
|
// not crash the process as an unhandled rejection.
|
|
595
658
|
d.promise.catch(() => { });
|
|
596
659
|
this._pendingCallbacks.set(key, d);
|
|
660
|
+
this._registerWaitingKey(key);
|
|
597
661
|
this._drainOrderedCompletions(completionOrderKey(durableTaskExternalId, invocationCount));
|
|
598
662
|
if (this._pendingCallbacks.has(key)) {
|
|
599
|
-
this.
|
|
663
|
+
this._scheduleWorkerStatusSend();
|
|
600
664
|
}
|
|
601
665
|
}
|
|
602
666
|
if (!signal) {
|
|
@@ -656,6 +720,10 @@ class DurableListenerClient {
|
|
|
656
720
|
sendEvictInvocation(durableTaskExternalId, invocationCount, reason) {
|
|
657
721
|
return __awaiter(this, void 0, void 0, function* () {
|
|
658
722
|
const key = evictionKey(durableTaskExternalId, invocationCount);
|
|
723
|
+
const pending = this._pendingEvictionAcks.get(key);
|
|
724
|
+
if (pending) {
|
|
725
|
+
return pending.promise;
|
|
726
|
+
}
|
|
659
727
|
const d = deferred();
|
|
660
728
|
this._pendingEvictionAcks.set(key, d);
|
|
661
729
|
const req = {
|
|
@@ -664,15 +732,17 @@ class DurableListenerClient {
|
|
|
664
732
|
reason,
|
|
665
733
|
};
|
|
666
734
|
this._enqueueRequest({ evictInvocation: req });
|
|
667
|
-
const timeout = (
|
|
668
|
-
|
|
669
|
-
});
|
|
735
|
+
const timeout = setTimeout(() => {
|
|
736
|
+
d.reject(new Error(`Eviction ack timed out after ${EVICTION_ACK_TIMEOUT_MS}ms for task ${durableTaskExternalId} invocation ${invocationCount}`));
|
|
737
|
+
}, EVICTION_ACK_TIMEOUT_MS);
|
|
670
738
|
try {
|
|
671
|
-
yield
|
|
739
|
+
yield d.promise;
|
|
672
740
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
741
|
+
finally {
|
|
742
|
+
clearTimeout(timeout);
|
|
743
|
+
if (this._pendingEvictionAcks.get(key) === d) {
|
|
744
|
+
this._pendingEvictionAcks.delete(key);
|
|
745
|
+
}
|
|
676
746
|
}
|
|
677
747
|
});
|
|
678
748
|
}
|
package/package.json
CHANGED
|
@@ -45,6 +45,7 @@ export declare class InternalWorker {
|
|
|
45
45
|
enableHealthServer: boolean;
|
|
46
46
|
private healthServer;
|
|
47
47
|
private status;
|
|
48
|
+
private shutdownPromise;
|
|
48
49
|
constructor(client: HatchetClient, options: {
|
|
49
50
|
name: string;
|
|
50
51
|
handleKill?: boolean;
|
|
@@ -96,6 +97,7 @@ export declare class InternalWorker {
|
|
|
96
97
|
handleCancelStepRun(action: Action): Promise<void>;
|
|
97
98
|
stop(): Promise<void>;
|
|
98
99
|
exitGracefully(handleKill: boolean): Promise<void>;
|
|
100
|
+
private shutdown;
|
|
99
101
|
/**
|
|
100
102
|
* Creates an action listener by registering the worker with the dispatcher.
|
|
101
103
|
* Override in subclasses to change registration behavior (e.g. legacy engines).
|
|
@@ -628,6 +628,18 @@ class InternalWorker {
|
|
|
628
628
|
exitGracefully(handleKill) {
|
|
629
629
|
return __awaiter(this, void 0, void 0, function* () {
|
|
630
630
|
var _a;
|
|
631
|
+
// Signals and an explicit stop must await the same eviction and listener teardown.
|
|
632
|
+
(_a = this.shutdownPromise) !== null && _a !== void 0 ? _a : (this.shutdownPromise = this.shutdown());
|
|
633
|
+
yield this.shutdownPromise;
|
|
634
|
+
if (handleKill) {
|
|
635
|
+
this.logger.info('Exiting hatchet worker...');
|
|
636
|
+
process.exit(0);
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
shutdown() {
|
|
641
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
642
|
+
var _a, _b;
|
|
631
643
|
this.killing = true;
|
|
632
644
|
this.setStatus(health_server_1.workerStatus.UNHEALTHY);
|
|
633
645
|
this.logger.info('Starting to exit...');
|
|
@@ -658,16 +670,19 @@ class InternalWorker {
|
|
|
658
670
|
catch (e) {
|
|
659
671
|
this.logger.error(`Could not stop durable listener: ${e.message}`);
|
|
660
672
|
}
|
|
673
|
+
(_a = this.listener) === null || _a === void 0 ? void 0 : _a.stopStream();
|
|
674
|
+
this.logger.info('Gracefully exiting hatchet worker, running tasks will attempt to finish...');
|
|
675
|
+
// attempt to wait for futures to finish
|
|
676
|
+
yield Promise.all(Object.values(this.futures).map(({ promise }) => promise));
|
|
677
|
+
this.logger.info('Successfully finished pending tasks.');
|
|
678
|
+
// Unregistering stops the heartbeat, so it has to wait until the running tasks are done:
|
|
679
|
+
// otherwise the engine sees a dead worker and reassigns tasks that are about to complete.
|
|
661
680
|
try {
|
|
662
|
-
yield ((
|
|
681
|
+
yield ((_b = this.listener) === null || _b === void 0 ? void 0 : _b.unregister());
|
|
663
682
|
}
|
|
664
683
|
catch (e) {
|
|
665
684
|
this.logger.error(`Could not unregister listener: ${e.message}`);
|
|
666
685
|
}
|
|
667
|
-
this.logger.info('Gracefully exiting hatchet worker, running tasks will attempt to finish...');
|
|
668
|
-
// attempt to wait for futures to finish
|
|
669
|
-
yield Promise.all(Object.values(this.futures).map(({ promise }) => promise));
|
|
670
|
-
this.logger.info('Successfully finished pending tasks.');
|
|
671
686
|
if (this.healthServer) {
|
|
672
687
|
try {
|
|
673
688
|
yield this.healthServer.stop();
|
|
@@ -676,10 +691,6 @@ class InternalWorker {
|
|
|
676
691
|
this.logger.error(`Could not stop health server: ${e.message}`);
|
|
677
692
|
}
|
|
678
693
|
}
|
|
679
|
-
if (handleKill) {
|
|
680
|
-
this.logger.info('Exiting hatchet worker...');
|
|
681
|
-
process.exit(0);
|
|
682
|
-
}
|
|
683
694
|
});
|
|
684
695
|
}
|
|
685
696
|
/**
|
|
@@ -700,10 +711,18 @@ class InternalWorker {
|
|
|
700
711
|
start() {
|
|
701
712
|
return __awaiter(this, void 0, void 0, function* () {
|
|
702
713
|
var _a, e_1, _b, _c;
|
|
714
|
+
if (this.killing) {
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
703
717
|
this.setStatus(health_server_1.workerStatus.STARTING);
|
|
704
718
|
if (this.healthServer) {
|
|
705
719
|
try {
|
|
706
720
|
yield this.healthServer.start();
|
|
721
|
+
if (this.killing) {
|
|
722
|
+
yield this.shutdownPromise;
|
|
723
|
+
yield this.healthServer.stop();
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
707
726
|
}
|
|
708
727
|
catch (e) {
|
|
709
728
|
this.logger.error(`Could not start health server: ${e.message}`);
|
|
@@ -713,11 +732,17 @@ class InternalWorker {
|
|
|
713
732
|
}
|
|
714
733
|
// ensure all workflows are registered
|
|
715
734
|
yield Promise.all(this.registeredWorkflowPromises);
|
|
716
|
-
if (Object.keys(this.action_registry).length === 0) {
|
|
735
|
+
if (this.killing || Object.keys(this.action_registry).length === 0) {
|
|
717
736
|
return;
|
|
718
737
|
}
|
|
719
738
|
try {
|
|
720
|
-
|
|
739
|
+
const listener = yield this.createListener();
|
|
740
|
+
if (this.killing) {
|
|
741
|
+
// Shutdown cannot clean up a listener that registration has not returned yet.
|
|
742
|
+
yield listener.unregister();
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
this.listener = listener;
|
|
721
746
|
this.workerId = this.listener.workerId;
|
|
722
747
|
this.setStatus(health_server_1.workerStatus.HEALTHY);
|
|
723
748
|
const generator = this.listener.actions();
|
package/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const HATCHET_VERSION = "1.34.
|
|
1
|
+
export declare const HATCHET_VERSION = "1.34.1";
|
package/version.js
CHANGED