@keetanetwork/anchor 0.0.39 → 0.0.41
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/client/index.d.ts +6 -0
- package/client/index.d.ts.map +1 -1
- package/client/index.js +7 -0
- package/client/index.js.map +1 -1
- package/lib/block-listener.d.ts +93 -0
- package/lib/block-listener.d.ts.map +1 -0
- package/lib/block-listener.js +259 -0
- package/lib/block-listener.js.map +1 -0
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +3 -1
- package/lib/error.js.map +1 -1
- package/lib/http-server/index.d.ts +14 -1
- package/lib/http-server/index.d.ts.map +1 -1
- package/lib/http-server/index.js +86 -7
- package/lib/http-server/index.js.map +1 -1
- package/lib/queue/index.d.ts +20 -5
- package/lib/queue/index.d.ts.map +1 -1
- package/lib/queue/index.js +52 -17
- package/lib/queue/index.js.map +1 -1
- package/lib/resolver.d.ts +57 -0
- package/lib/resolver.d.ts.map +1 -1
- package/lib/resolver.js +864 -250
- package/lib/resolver.js.map +1 -1
- package/npm-shrinkwrap.json +4 -4
- package/package.json +1 -1
- package/services/asset-movement/client.d.ts +9 -2
- package/services/asset-movement/client.d.ts.map +1 -1
- package/services/asset-movement/client.js +35 -2
- package/services/asset-movement/client.js.map +1 -1
- package/services/asset-movement/common.d.ts +1 -0
- package/services/asset-movement/common.d.ts.map +1 -1
- package/services/asset-movement/common.js +75 -0
- package/services/asset-movement/common.js.map +1 -1
- package/services/asset-movement/server.d.ts +0 -10
- package/services/asset-movement/server.d.ts.map +1 -1
- package/services/asset-movement/server.js +0 -2
- package/services/asset-movement/server.js.map +1 -1
- package/services/fx/common.d.ts +1 -1
- package/services/fx/common.js.map +1 -1
- package/services/fx/server.d.ts +37 -6
- package/services/fx/server.d.ts.map +1 -1
- package/services/fx/server.js +207 -66
- package/services/fx/server.js.map +1 -1
- package/services/storage/client.d.ts +332 -0
- package/services/storage/client.d.ts.map +1 -0
- package/services/storage/client.js +1078 -0
- package/services/storage/client.js.map +1 -0
- package/services/storage/clients/contacts.d.ts +94 -0
- package/services/storage/clients/contacts.d.ts.map +1 -0
- package/services/storage/clients/contacts.generated.d.ts +3 -0
- package/services/storage/clients/contacts.generated.d.ts.map +1 -0
- package/services/storage/clients/contacts.generated.js +1197 -0
- package/services/storage/clients/contacts.generated.js.map +1 -0
- package/services/storage/clients/contacts.js +141 -0
- package/services/storage/clients/contacts.js.map +1 -0
- package/services/storage/common.d.ts +667 -0
- package/services/storage/common.d.ts.map +1 -0
- package/services/storage/common.generated.d.ts +17 -0
- package/services/storage/common.generated.d.ts.map +1 -0
- package/services/storage/common.generated.js +863 -0
- package/services/storage/common.generated.js.map +1 -0
- package/services/storage/common.js +587 -0
- package/services/storage/common.js.map +1 -0
- package/services/storage/lib/validators.d.ts +64 -0
- package/services/storage/lib/validators.d.ts.map +1 -0
- package/services/storage/lib/validators.js +82 -0
- package/services/storage/lib/validators.js.map +1 -0
- package/services/storage/server.d.ts +127 -0
- package/services/storage/server.d.ts.map +1 -0
- package/services/storage/server.js +626 -0
- package/services/storage/server.js.map +1 -0
- package/services/storage/test-utils.d.ts +70 -0
- package/services/storage/test-utils.d.ts.map +1 -0
- package/services/storage/test-utils.js +347 -0
- package/services/storage/test-utils.js.map +1 -0
- package/services/storage/utils.d.ts +3 -0
- package/services/storage/utils.d.ts.map +1 -0
- package/services/storage/utils.js +10 -0
- package/services/storage/utils.js.map +1 -0
- package/services/username/client.d.ts +145 -0
- package/services/username/client.d.ts.map +1 -0
- package/services/username/client.js +681 -0
- package/services/username/client.js.map +1 -0
- package/services/username/common.d.ts +136 -0
- package/services/username/common.d.ts.map +1 -0
- package/services/username/common.generated.d.ts +13 -0
- package/services/username/common.generated.d.ts.map +1 -0
- package/services/username/common.generated.js +256 -0
- package/services/username/common.generated.js.map +1 -0
- package/services/username/common.js +226 -0
- package/services/username/common.js.map +1 -0
- package/services/username/server.d.ts +49 -0
- package/services/username/server.d.ts.map +1 -0
- package/services/username/server.js +262 -0
- package/services/username/server.js.map +1 -0
package/lib/queue/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { __addDisposableResource, __disposeResources } from "tslib";
|
|
2
|
+
import { assertNever } from '../utils/never.js';
|
|
2
3
|
import { asleep } from '../utils/asleep.js';
|
|
3
4
|
import { Errors } from './common.js';
|
|
4
5
|
import { MethodLogger, ManageStatusUpdates, ConvertStringToRequestID } from './internal.js';
|
|
@@ -344,6 +345,16 @@ export class KeetaAnchorQueueRunner {
|
|
|
344
345
|
})();
|
|
345
346
|
return (await this.initializePromise);
|
|
346
347
|
}
|
|
348
|
+
setConfiguration(parameters) {
|
|
349
|
+
const parameterNames = ['batchSize', 'maxRetries', 'processTimeout', 'retryDelay', 'stuckMultiplier'];
|
|
350
|
+
for (const parameterName of parameterNames) {
|
|
351
|
+
const value = parameters[parameterName];
|
|
352
|
+
if (value === undefined) {
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
this[parameterName] = value;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
347
358
|
methodLogger(method) {
|
|
348
359
|
return (MethodLogger(this.logger, {
|
|
349
360
|
class: 'KeetaAnchorQueueRunner',
|
|
@@ -358,12 +369,11 @@ export class KeetaAnchorQueueRunner {
|
|
|
358
369
|
throw (new Error('This is a testing only method'));
|
|
359
370
|
}
|
|
360
371
|
return ({
|
|
361
|
-
setParams: (
|
|
362
|
-
|
|
363
|
-
this.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
this.maxRunners = maxWorkers;
|
|
372
|
+
setParams: (params) => {
|
|
373
|
+
const { maxRunners, ...configParams } = params;
|
|
374
|
+
this.setConfiguration(configParams);
|
|
375
|
+
if (maxRunners !== undefined) {
|
|
376
|
+
this.maxRunners = maxRunners;
|
|
367
377
|
}
|
|
368
378
|
},
|
|
369
379
|
queue: () => {
|
|
@@ -640,6 +650,9 @@ export class KeetaAnchorQueueRunner {
|
|
|
640
650
|
*/
|
|
641
651
|
const pipes = [...this.pipes];
|
|
642
652
|
for (const pipe of pipes) {
|
|
653
|
+
if (pipe.exclusiveTarget === false) {
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
643
656
|
let remainingTime = undefined;
|
|
644
657
|
if (timeout !== undefined) {
|
|
645
658
|
const elapsed = Date.now() - startTime;
|
|
@@ -756,6 +769,15 @@ export class KeetaAnchorQueueRunner {
|
|
|
756
769
|
const sentCount = RequestSentToPipes.get(requestID) ?? 0;
|
|
757
770
|
RequestSentToPipes.set(requestID, sentCount + 1);
|
|
758
771
|
}
|
|
772
|
+
const getNextPipeRequestInput = (entry) => {
|
|
773
|
+
if (statusTarget === 'completed') {
|
|
774
|
+
return (this.decodeResponse(entry.output));
|
|
775
|
+
}
|
|
776
|
+
else if (statusTarget === 'failed_permanently') {
|
|
777
|
+
return (this.decodeRequest(entry.request));
|
|
778
|
+
}
|
|
779
|
+
assertNever(statusTarget);
|
|
780
|
+
};
|
|
759
781
|
for (const pipe of pipes) {
|
|
760
782
|
logger?.debug('Processing pipe to target', pipe.target.id, pipe.isBatchPipe ? '(batch pipe)' : '(single item pipe)');
|
|
761
783
|
if (pipe.isBatchPipe) {
|
|
@@ -801,7 +823,7 @@ export class KeetaAnchorQueueRunner {
|
|
|
801
823
|
* the entries which have non-null outputs
|
|
802
824
|
*/
|
|
803
825
|
const batchRaw = requests.map((entry) => {
|
|
804
|
-
return ({ output:
|
|
826
|
+
return ({ output: getNextPipeRequestInput(entry), id: entry.id });
|
|
805
827
|
}).filter(function (entry) {
|
|
806
828
|
if (entry === null) {
|
|
807
829
|
return (false);
|
|
@@ -839,6 +861,8 @@ export class KeetaAnchorQueueRunner {
|
|
|
839
861
|
});
|
|
840
862
|
logger?.debug(`Moving batch of ${batchOutput.length} ${statusTarget} requests to next pipe`, pipe.target.id, '(input entry IDs:', Array.from(batchLocalIDs), '->', `${pipe.target.id}:${String(batchID)})`);
|
|
841
863
|
try {
|
|
864
|
+
// There is no way for typescript to cleanly infer the type here, so we assert it.
|
|
865
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
842
866
|
await pipe.target.add(batchOutput, {
|
|
843
867
|
id: batchID,
|
|
844
868
|
/* Use the set of IDs as the idempotent IDs for the batch */
|
|
@@ -884,12 +908,14 @@ export class KeetaAnchorQueueRunner {
|
|
|
884
908
|
for (const request of requests) {
|
|
885
909
|
let shouldMarkAsMoved = true;
|
|
886
910
|
try {
|
|
887
|
-
const output =
|
|
911
|
+
const output = getNextPipeRequestInput(request);
|
|
888
912
|
if (output === null) {
|
|
889
913
|
logger?.debug(`Completed request with id ${String(request.id)} has no output -- next stage will not be run`);
|
|
890
914
|
}
|
|
891
915
|
else {
|
|
892
916
|
logger?.debug(`Moving ${statusTarget} request with id ${String(request.id)} to next pipe`, pipe.target.id);
|
|
917
|
+
// There is no way for typescript to cleanly infer the type here, so we assert it.
|
|
918
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
893
919
|
await pipe.target.add(output, { id: request.id });
|
|
894
920
|
}
|
|
895
921
|
}
|
|
@@ -954,6 +980,9 @@ export class KeetaAnchorQueueRunner {
|
|
|
954
980
|
}
|
|
955
981
|
for (const pipe of this.pipes) {
|
|
956
982
|
try {
|
|
983
|
+
if (pipe.exclusiveTarget === false) {
|
|
984
|
+
continue;
|
|
985
|
+
}
|
|
957
986
|
await pipe.target.maintain();
|
|
958
987
|
}
|
|
959
988
|
catch (error) {
|
|
@@ -972,16 +1001,18 @@ export class KeetaAnchorQueueRunner {
|
|
|
972
1001
|
/**
|
|
973
1002
|
* Pipe the the completed entries of this runner to another runner
|
|
974
1003
|
*/
|
|
975
|
-
pipe(target) {
|
|
1004
|
+
pipe(target, options) {
|
|
976
1005
|
this.pipes.push({
|
|
1006
|
+
...options,
|
|
977
1007
|
isBatchPipe: false,
|
|
978
1008
|
target: target,
|
|
979
1009
|
acceptStatus: 'completed'
|
|
980
1010
|
});
|
|
981
1011
|
return (target);
|
|
982
1012
|
}
|
|
983
|
-
pipeFailed(target) {
|
|
1013
|
+
pipeFailed(target, options) {
|
|
984
1014
|
this.pipes.push({
|
|
1015
|
+
...options,
|
|
985
1016
|
isBatchPipe: false,
|
|
986
1017
|
target: target,
|
|
987
1018
|
acceptStatus: 'failed_permanently'
|
|
@@ -991,8 +1022,9 @@ export class KeetaAnchorQueueRunner {
|
|
|
991
1022
|
/**
|
|
992
1023
|
* Pipe batches of completed entries from this runner to another runner
|
|
993
1024
|
*/
|
|
994
|
-
pipeBatch(target, maxBatchSize = 100, minBatchSize = 1) {
|
|
1025
|
+
pipeBatch(target, maxBatchSize = 100, minBatchSize = 1, options) {
|
|
995
1026
|
this.pipes.push({
|
|
1027
|
+
...options,
|
|
996
1028
|
isBatchPipe: true,
|
|
997
1029
|
target: target,
|
|
998
1030
|
minBatchSize: minBatchSize,
|
|
@@ -1001,8 +1033,9 @@ export class KeetaAnchorQueueRunner {
|
|
|
1001
1033
|
});
|
|
1002
1034
|
return (target);
|
|
1003
1035
|
}
|
|
1004
|
-
pipeBatchFailed(target, maxBatchSize = 100, minBatchSize = 1) {
|
|
1036
|
+
pipeBatchFailed(target, maxBatchSize = 100, minBatchSize = 1, options) {
|
|
1005
1037
|
this.pipes.push({
|
|
1038
|
+
...options,
|
|
1006
1039
|
isBatchPipe: true,
|
|
1007
1040
|
target: target,
|
|
1008
1041
|
minBatchSize: minBatchSize,
|
|
@@ -1046,13 +1079,15 @@ export class KeetaAnchorQueueRunnerJSONConfigProc extends KeetaAnchorQueueRunner
|
|
|
1046
1079
|
processor;
|
|
1047
1080
|
constructor(config) {
|
|
1048
1081
|
super(config);
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1082
|
+
const { processor, processorStuck, processorAborted, ...parameters } = config;
|
|
1083
|
+
this.processor = processor;
|
|
1084
|
+
if (processorStuck) {
|
|
1085
|
+
this.processorStuck = processorStuck;
|
|
1052
1086
|
}
|
|
1053
|
-
if (
|
|
1054
|
-
this.processorAborted =
|
|
1087
|
+
if (processorAborted) {
|
|
1088
|
+
this.processorAborted = processorAborted;
|
|
1055
1089
|
}
|
|
1090
|
+
this.setConfiguration(parameters);
|
|
1056
1091
|
}
|
|
1057
1092
|
}
|
|
1058
1093
|
//# sourceMappingURL=index.js.map
|
package/lib/queue/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/queue/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BrandedString, Brand } from '../utils/brand.ts';\nimport type { Logger } from '../log/index.ts';\nimport type { JSONSerializable } from '../utils/json.ts';\nimport type { AssertNever } from '../utils/never.ts';\nimport type { KeetaAnchorQueueRunOptions } from './common.js';\nimport { asleep } from '../utils/asleep.js';\nimport { Errors } from './common.js';\nimport {\n\tMethodLogger,\n\tManageStatusUpdates,\n\tConvertStringToRequestID\n} from './internal.js';\nimport { AsyncDisposableStack } from '../utils/defer.js';\n\nexport type KeetaAnchorQueueRequest<QueueRequest> = QueueRequest;\nexport type KeetaAnchorQueueRequestID = BrandedString<'KeetaAnchorQueueID'>;\nexport type KeetaAnchorQueueWorkerID = Brand<number, 'KeetaAnchorQueueWorkerID'>;\n\nexport type KeetaAnchorQueueStatus = 'pending' | 'processing' | 'completed' | 'failed_temporarily' | 'failed_permanently' | 'stuck' | 'aborted' | 'moved' | '@internal';\nconst keetaAnchorPipeableQueueStatuses = [ 'completed', 'failed_permanently' ] as const;\n/**\n * This is a type-level assertion to ensure that all values in keetaAnchorPipeableQueueStatuses are valid KeetaAnchorQueueStatus values.\n * If this assertion fails, it means that there is a value in keetaAnchorPipeableQueueStatuses that is not a valid KeetaAnchorQueueStatus, and the code will not compile.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype __check_keetaAnchorPipeableQueueStatuses_valid = AssertNever<typeof keetaAnchorPipeableQueueStatuses[number] extends KeetaAnchorQueueStatus ? never : true>;\n\nexport type KeetaAnchorPipeableQueueStatus = Extract<KeetaAnchorQueueStatus, typeof keetaAnchorPipeableQueueStatuses[number]>;\nexport type KeetaAnchorQueueEntry<QueueRequest, QueueResult> = {\n\t/**\n\t * The Job ID\n\t */\n\tid: KeetaAnchorQueueRequestID;\n\t/**\n\t * Idempotent IDs from a previous stage\n\t */\n\tidempotentKeys?: Set<KeetaAnchorQueueRequestID> | undefined;\n\trequest: KeetaAnchorQueueRequest<QueueRequest>;\n\toutput: QueueResult | null;\n\tlastError: string | null;\n\tstatus: KeetaAnchorQueueStatus;\n\tcreated: Date;\n\tupdated: Date;\n\tworker: KeetaAnchorQueueWorkerID | null;\n\tfailures: number;\n};\n\n/**\n * Extra information to provide to a request when adding an entry to the queue\n */\nexport type KeetaAnchorQueueEntryExtra = {\n\t[key in 'idempotentKeys' | 'id' | 'status']?: (key extends 'id' ? KeetaAnchorQueueRequestID | string : KeetaAnchorQueueEntry<never, never>[key]) | undefined;\n};\n\nexport type KeetaAnchorQueueFilter = {\n\t/**\n\t * Only return entries with this status\n\t */\n\tstatus?: KeetaAnchorQueueStatus;\n\t/**\n\t * Only return entries last updated before this date\n\t */\n\tupdatedBefore?: Date;\n\t/**\n\t * Limit the number of entries returned\n\t */\n\tlimit?: number;\n};\n\nexport type KeetaAnchorQueueCommonOptions = {\n\tlogger?: Logger | undefined;\n\tid?: string | undefined;\n};\n\nexport type KeetaAnchorQueueRunnerOptions = KeetaAnchorQueueCommonOptions & {\n\t/**\n\t * If specified, then multiple workers can be used to process this queue\n\t * in parallel by splitting the work among the workers.\n\t *\n\t * By default, only a single worker will process the queue (count=1, id=0)\n\t */\n\tworkers?: {\n\t\tcount: number;\n\t\tid: number;\n\t} | undefined;\n};\n\nexport type KeetaAnchorQueueStorageOptions = KeetaAnchorQueueCommonOptions & {\n\tpath?: string[] | undefined;\n};\n\nexport type KeetaAnchorQueueEntryAncillaryData<QueueResult> = {\n\t/**\n\t * The previous status of the entry -- if the entry is not currently in this status,\n\t * the status update will fail\n\t */\n\toldStatus?: KeetaAnchorQueueStatus | undefined;\n\t/**\n\t * The worker ID performing the status update\n\t */\n\tby?: KeetaAnchorQueueWorkerID | undefined;\n\t/**\n\t * The output data to store with the entry\n\t */\n\toutput?: QueueResult | null | undefined;\n\t/**\n\t * An error message to store with the entry\n\t */\n\terror?: string | undefined;\n};\n\nexport type KeetaAnchorQueueStorageDriverConstructor<QueueRequest extends JSONSerializable, QueueResult extends JSONSerializable> = new(options?: KeetaAnchorQueueStorageOptions) => KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>;\n\nexport interface KeetaAnchorQueueStorageDriver<QueueRequest extends JSONSerializable, QueueResult extends JSONSerializable> {\n\t/**\n\t * An ID for this instance of the storage driver\n\t */\n\treadonly id: string;\n\n\t/**\n\t * The name of the storage driver\n\t */\n\treadonly name: string;\n\n\t/**\n\t * The partition ID for this instance of the storage driver\n\t *\n\t * This is used to divide a single storage backend into multiple\n\t * independent queues.\n\t *\n\t * The root partition is an empty array, and each element is\n\t * a hierarchical partition name.\n\t */\n\treadonly path: string[];\n\n\t/**\n\t * Enqueue an item to be processed by the queue\n\t *\n\t * It will be inserted into the queue as a 'pending' entry\n\t *\n\t * @param request The request to enqueue\n\t * @param id Optional ID to use for the entry -- if not provided, a new\n\t * ID will be generated. If the ID is already in use then\n\t * nothing will be added.\n\t * @returns The ID for the newly created pending entry\n\t */\n\tadd: (request: KeetaAnchorQueueRequest<QueueRequest>, info?: KeetaAnchorQueueEntryExtra) => Promise<KeetaAnchorQueueRequestID>;\n\n\t/**\n\t * Update the status of an entry in the queue\n\t *\n\t * If the status is \"failed_temporarily\", the failure count will be incremented\n\t *\n\t * @param id The entry ID to update\n\t * @param status The new status of the entry\n\t * @param ancillary Optional ancillary data for the status update\n\t * @returns void\n\t */\n\tsetStatus: (id: KeetaAnchorQueueRequestID, status: KeetaAnchorQueueStatus, ancillary?: KeetaAnchorQueueEntryAncillaryData<QueueResult>) => Promise<void>;\n\n\t/**\n\t * Get entries from storage with an optional filter\n\t *\n\t * @param filter The filter to apply (optional)\n\t * @returns An array of entries matching the criteria\n\t */\n\tquery(filter?: KeetaAnchorQueueFilter): Promise<KeetaAnchorQueueEntry<QueueRequest, QueueResult>[]>;\n\n\t/**\n\t * Get a single entry from storage by ID\n\t *\n\t * @param id The ID of the entry to retrieve\n\t * @returns The entry if found, or null if not found\n\t */\n\tget(id: KeetaAnchorQueueRequestID): Promise<KeetaAnchorQueueEntry<QueueRequest, QueueResult> | null>;\n\n\t/**\n\t * Perform maintenance tasks on the storage driver\n\t * (e.g. cleaning up old entries, etc)\n\t *\n\t * @returns void\n\t */\n\tmaintain?: () => Promise<void>;\n\n\t/**\n\t * Create a partitioned view of the queue\n\t *\n\t * @param partitionID The partition ID to use\n\t * @returns A new storage driver instance for the partition\n\t */\n\tpartition: (path: string) => Promise<KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>>;\n\n\t/**\n\t * Close the storage driver and release any resources\n\t */\n\tdestroy(): Promise<void>;\n\t[Symbol.asyncDispose](): Promise<void>;\n\n\t/** @internal */\n\t_Testing?: (key: string) => {\n\t\tsetToctouDelay?(delay: number): void;\n\t\tunsetToctouDelay?(): void;\n\t};\n}\n\n/**\n * An in-memory implementation of the KeetaAnchorQueueStorageDriver\n */\nexport class KeetaAnchorQueueStorageDriverMemory<QueueRequest extends JSONSerializable = JSONSerializable, QueueResult extends JSONSerializable = JSONSerializable> implements KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult> {\n\tprotected queueStorage: { [path: string]: KeetaAnchorQueueEntry<QueueRequest, QueueResult>[]; } = {};\n\tprotected readonly logger?: Logger | undefined;\n\tprotected partitionCounter = 0;\n\tprivate destroyed = false;\n\treadonly name: string = 'KeetaAnchorQueueStorageDriverMemory';\n\treadonly id: string;\n\treadonly path: string[] = [];\n\n\tconstructor(options?: KeetaAnchorQueueStorageOptions) {\n\t\tthis.id = options?.id ?? crypto.randomUUID();\n\t\tthis.logger = options?.logger;\n\t\tthis.path.push(...(options?.path ?? []));\n\t\tObject.freeze(this.path);\n\n\t\tthis.methodLogger('new')?.debug('Created new in-memory queue storage driver');\n\t}\n\n\tprotected clone(options?: Partial<KeetaAnchorQueueStorageOptions>): KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult> {\n\t\tconst cloned = new KeetaAnchorQueueStorageDriverMemory<QueueRequest, QueueResult>({\n\t\t\tlogger: this.logger,\n\t\t\tid: `${this.id}::${this.partitionCounter++}`,\n\t\t\tpath: [...this.path],\n\t\t\t...options\n\t\t});\n\t\tcloned.queueStorage = this.queueStorage;\n\n\t\treturn(cloned);\n\t}\n\n\tprotected get queue(): KeetaAnchorQueueEntry<QueueRequest, QueueResult>[] {\n\t\tconst pathKey = ['root', ...this.path].join('.');\n\t\tlet retval = this.queueStorage[pathKey];\n\t\tif (retval === undefined) {\n\t\t\tretval = this.queueStorage[pathKey] = [];\n\t\t}\n\t\treturn(retval);\n\t}\n\n\tprotected methodLogger(method: string): Logger | undefined {\n\t\treturn(MethodLogger(this.logger, {\n\t\t\tclass: 'KeetaAnchorQueueStorageDriverMemory',\n\t\t\tfile: 'src/lib/queue/index.ts',\n\t\t\tmethod: method,\n\t\t\tinstanceID: this.id\n\t\t}));\n\t}\n\n\tprivate checkDestroyed(): void {\n\t\tif (this.destroyed) {\n\t\t\tthrow(new Error('Queue has been destroyed'));\n\t\t}\n\t}\n\n\tasync add(request: KeetaAnchorQueueRequest<QueueRequest>, info?: KeetaAnchorQueueEntryExtra): Promise<KeetaAnchorQueueRequestID> {\n\t\tthis.checkDestroyed();\n\n\t\tconst logger = this.methodLogger('add');\n\n\t\tlet id = ConvertStringToRequestID(info?.id);\n\t\tif (id) {\n\t\t\tconst duplicateID = this.queue.some(function(checkEntry) {\n\t\t\t\treturn(checkEntry.id === id);\n\t\t\t});\n\n\t\t\tif (duplicateID) {\n\t\t\t\tlogger?.debug(`Request with id ${String(id)} already exists, ignoring`);\n\n\t\t\t\treturn(id);\n\t\t\t}\n\t\t}\n\n\t\tconst idempotentIDs = info?.idempotentKeys;\n\t\tif (idempotentIDs) {\n\t\t\tconst matchingIdempotentEntries = new Set<KeetaAnchorQueueRequestID>();\n\t\t\tfor (const idempotentID of idempotentIDs) {\n\t\t\t\tconst idempotentEntryExists = this.queue.some(function(checkEntry) {\n\t\t\t\t\treturn(checkEntry.idempotentKeys?.has(idempotentID) ?? false);\n\t\t\t\t});\n\n\t\t\t\tif (idempotentEntryExists) {\n\t\t\t\t\tmatchingIdempotentEntries.add(idempotentID);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matchingIdempotentEntries.size !== 0) {\n\t\t\t\tthrow(new Errors.IdempotentExistsError('One or more idempotent entries already exist in the queue', matchingIdempotentEntries));\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * The status to use for the new entry\n\t\t */\n\t\tconst status = info?.status ?? 'pending';\n\n\t\t/*\n\t\t * The ID is a branded string, so we must convert the generated UUID\n\t\t */\n\t\tid ??= ConvertStringToRequestID(crypto.randomUUID());\n\n\t\tlogger?.debug(`Enqueuing request with id ${String(id)}`);\n\n\t\tthis.queue.push({\n\t\t\tid: id,\n\t\t\trequest: request,\n\t\t\toutput: null,\n\t\t\tlastError: null,\n\t\t\tstatus: status,\n\t\t\tfailures: 0,\n\t\t\tcreated: new Date(),\n\t\t\tupdated: new Date(),\n\t\t\tworker: null,\n\t\t\tidempotentKeys: idempotentIDs ? new Set(idempotentIDs) : undefined\n\t\t});\n\n\t\treturn(id);\n\t}\n\n\tasync setStatus(id: KeetaAnchorQueueRequestID, status: KeetaAnchorQueueStatus, ancillary?: KeetaAnchorQueueEntryAncillaryData<QueueResult>): Promise<void> {\n\t\tthis.checkDestroyed();\n\n\t\tconst logger = this.methodLogger('setStatus');\n\n\t\tconst entry = this.queue.find(function(checkEntry) {\n\t\t\treturn(checkEntry.id === id);\n\t\t});\n\t\tif (!entry) {\n\t\t\tthrow(new Error(`Request with ID ${String(id)} not found`));\n\t\t}\n\n\t\tconst changedFields = ManageStatusUpdates<QueueResult>(id, entry, status, ancillary, logger);\n\n\t\tObject.assign(entry, changedFields);\n\t}\n\n\tasync get(id: KeetaAnchorQueueRequestID): Promise<KeetaAnchorQueueEntry<QueueRequest, QueueResult> | null> {\n\t\tthis.checkDestroyed();\n\n\t\tconst entry = this.queue.find(function(checkEntry) {\n\t\t\treturn(checkEntry.id === id);\n\t\t});\n\n\t\tif (!entry) {\n\t\t\treturn(null);\n\t\t}\n\n\t\treturn(structuredClone(entry));\n\t}\n\n\tasync query(filter?: KeetaAnchorQueueFilter): Promise<KeetaAnchorQueueEntry<QueueRequest, QueueResult>[]> {\n\t\tthis.checkDestroyed();\n\n\t\tconst logger = this.methodLogger('query');\n\n\t\tconst queueDuplicate = structuredClone(this.queue);\n\n\t\tlogger?.debug(`Querying queue with id ${this.id} with filter:`, filter);\n\n\t\tconst allEntriesInStatus = (function() {\n\t\t\tconst filterStatus = filter?.status;\n\t\t\tconst filterLastUpdateBefore = filter?.updatedBefore;\n\t\t\tif (filterStatus || filterLastUpdateBefore) {\n\t\t\t\treturn(queueDuplicate.filter(function(entry) {\n\t\t\t\t\tif (filterStatus) {\n\t\t\t\t\t\tif (entry.status !== filterStatus) {\n\t\t\t\t\t\t\treturn(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (filterLastUpdateBefore) {\n\t\t\t\t\t\tif (entry.updated >= filterLastUpdateBefore) {\n\t\t\t\t\t\t\treturn(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn(true);\n\t\t\t\t}));\n\t\t\t} else {\n\t\t\t\treturn(queueDuplicate);\n\t\t\t}\n\t\t})();\n\n\t\tlet retval = allEntriesInStatus;\n\t\tif (filter?.limit !== undefined) {\n\t\t\tretval = allEntriesInStatus.slice(0, filter.limit);\n\t\t}\n\n\t\tlogger?.debug(`Queried queue with id ${this.id} with filter:`, filter, '-- found', retval.length, 'entries');\n\n\t\treturn(retval);\n\t}\n\n\tasync partition(path: string): Promise<KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>> {\n\t\tthis.checkDestroyed();\n\n\t\tconst logger = this.methodLogger('partition');\n\n\t\tlogger?.debug(`Creating partitioned queue storage driver for path \"${path}\"`);\n\n\t\tconst partitioned = this.clone({\n\t\t\tpath: [...this.path, path]\n\t\t});\n\n\t\treturn(partitioned);\n\t}\n\n\tasync destroy(): Promise<void> {\n\t\tthis.destroyed = true;\n\t\tthis.methodLogger('destroy')?.debug('Destroying in-memory queue');\n\t}\n\n\tasync [Symbol.asyncDispose](): Promise<void> {\n\t\treturn(await this.destroy());\n\t}\n}\n\n/**\n * A Queue Runner and Request Translator for processing entries in a queue\n *\n * The queue runner is responsible for pulling entries from the queue,\n * processing them, and updating their status in the queue. As well\n * as moving jobs between queues by piping the output of one runner\n * to another. Additionally, maintenance tasks such as re-queuing\n * failed jobs and marking stuck jobs are also handled by the runner.\n *\n * This is an abstract base class that must be extended to provide\n * the actual processing logic as well as the encoding and decoding\n * for requests and responses.\n */\nexport abstract class KeetaAnchorQueueRunner<UserRequest = unknown, UserResult = unknown, QueueRequest extends JSONSerializable = JSONSerializable, QueueResult extends JSONSerializable = JSONSerializable> {\n\t/**\n\t * The queue this runner is responsible for running\n\t */\n\tprivate readonly queue: KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>;\n\t/**\n\t * The logger we should use for logging anything\n\t */\n\tprivate readonly logger?: Logger | undefined;\n\t/**\n\t * The processor function to use for processing entries\n\t */\n\tprotected abstract processor(entry: KeetaAnchorQueueEntry<UserRequest, UserResult>): Promise<{ status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; }>;\n\n\t/**\n\t * The processor for stuck jobs (optional)\n\t */\n\tprotected processorStuck?(entry: KeetaAnchorQueueEntry<UserRequest, UserResult>): Promise<{ status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; }>;\n\n\t/**\n\t * The processor for aborted jobs (optional)\n\t */\n\tprotected processorAborted?(entry: KeetaAnchorQueueEntry<UserRequest, UserResult>): Promise<{ status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; }>;\n\n\t/**\n\t * Worker configuration\n\t */\n\tprivate readonly workers: NonNullable<KeetaAnchorQueueRunnerOptions['workers']>;\n\tprivate readonly workerID: KeetaAnchorQueueWorkerID;\n\n\t/**\n\t * Pipes to other runners we have registered\n\t */\n\tprivate readonly pipes: (({\n\t\tisBatchPipe: false;\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\ttarget: KeetaAnchorQueueRunner<UserResult, any, QueueResult, any>\n\t} | {\n\t\tisBatchPipe: true;\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\ttarget: KeetaAnchorQueueRunner<UserResult[], any, JSONSerializable, any>;\n\t\tminBatchSize: number;\n\t\tmaxBatchSize: number;\n\t}) & {\n\t\tacceptStatus: KeetaAnchorPipeableQueueStatus;\n\t})[] = [];\n\n\t/**\n\t * Initialization promise\n\t */\n\tprivate initializePromise: Promise<void> | undefined;\n\n\t/**\n\t * Configuration for this queue\n\t */\n\t/**\n\t * The maximum number of times to retry a failed job before giving up\n\t * and marking it as permanently failed\n\t */\n\tprotected maxRetries = 5;\n\t/**\n\t * The amount of time to allow a job to run before considering it\n\t * timed out and marking it as aborted, the `aborted` processor\n\t * (if provided) will be responsible for determining what to do with\n\t * the job at that point (e.g. retry it, mark it as failed, etc)\n\t * because some work from the job may have been completed\n\t * before the timeout was reached -- it could even still be on-going\n\t * after the timeout is reached, so the `aborted` processor should be\n\t * prepared to handle that situation as well.\n\t */\n\tprotected processTimeout = 300_000; /* 5 minutes */\n\t/**\n\t * When piping a batch of jobs to another runner, this is the number\n\t * of jobs to include in each batch (max).\n\t */\n\tprotected batchSize = 100;\n\n\t/**\n\t * The amount of time to wait before retrying a failed job -- this should\n\t * be long enough to allow any transient issues to be resolved (e.g. a downstream\n\t * service to come back up, etc) but not so long that it causes excessive\n\t * delays in processing.\n\t *\n\t * Keep in mind that after the {@link maxRetries} is reached, the job will\n\t * be marked as permanently failed, so if the retry delay is too low then\n\t * it could cause jobs to be marked as permanently failed before transient\n\t * issues have a chance to be resolved.\n\t */\n\tprotected get retryDelay(): number {\n\t\tif (this.internalRetryDelay !== undefined) {\n\t\t\treturn(this.internalRetryDelay);\n\t\t}\n\t\treturn(this.processTimeout * 10);\n\t}\n\n\tprotected set retryDelay(value: number) {\n\t\tthis.internalRetryDelay = value;\n\t}\n\n\tprivate internalRetryDelay?: number;\n\n\t/**\n\t * The number of {@link processTimeout} intervals to wait before\n\t * considering a job to be stuck -- this is for jobs that are\n\t * still in the 'processing' state but have not updated their\n\t * timestamp in a long time, which likely indicates that the worker\n\t * processing the job has died or is otherwise no longer making\n\t * progress on the job.\n\t *\n\t * Like the `aborted` status, the `stuck` status means the job is in\n\t * an indeterminate state where it may have done some of the work of\n\t * the processor but we don't know how much (if any) of it was\n\t * completed, so the `stuck` processor should be prepared to handle\n\t * that situation. It is unlikely that the job is still being actively\n\t * processed by a worker at this point, but it is possible, so the\n\t * `stuck` processor should be prepared to handle that as well.\n\t */\n\tprotected get stuckMultiplier(): number {\n\t\tif (this.internalStuckMultiplier !== undefined) {\n\t\t\treturn(this.internalStuckMultiplier);\n\t\t}\n\t\treturn(10);\n\t}\n\n\tprotected set stuckMultiplier(value: number) {\n\t\tthis.internalStuckMultiplier = value;\n\t}\n\n\tprivate internalStuckMultiplier?: number;\n\n\t/**\n\t * How many runners can process this queue in parallel\n\t */\n\tprotected maxRunners?: number;\n\tprivate readonly runnerLockKey: KeetaAnchorQueueRequestID;\n\n\t/**\n\t * The ID of this runner for diagnostic purposes\n\t */\n\treadonly id: string;\n\n\tconstructor(config: { queue: KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>; } & KeetaAnchorQueueRunnerOptions) {\n\t\tthis.queue = config.queue;\n\t\tthis.logger = config.logger;\n\t\tthis.workers = config.workers ?? {\n\t\t\tcount: 1,\n\t\t\tid: 0\n\t\t};\n\n\t\tif (this.workers.id < 0) {\n\t\t\tthrow(new Error('Worker ID cannot be negative'));\n\t\t}\n\n\t\tif (this.maxRunners) {\n\t\t\tif (this.workers.id > this.maxRunners - 1 || this.workers.count > this.maxRunners) {\n\t\t\t\tthrow(new Error('Worker ID other than 0 or worker count other than 1 is not supported yet'));\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * The worker ID is just a branded version of the worker number\n\t\t */\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\tthis.workerID = this.workers.id as KeetaAnchorQueueWorkerID;\n\n\t\t/*\n\t\t * The runner lock key, a unique key used to ensure only\n\t\t * one instance of a given runner is running at a time\n\t\t */\n\t\tthis.runnerLockKey = ConvertStringToRequestID(`@runner-lock:9ba756f0-7aa2-41c7-a1ea-b010dc752ae8.worker.${this.workerID}`);\n\n\t\t/**\n\t\t * Instance ID\n\t\t */\n\t\tthis.id = config.id ?? crypto.randomUUID();\n\n\t\tthis.methodLogger('new')?.debug('Created new queue runner attached to queue', this.queue.id);\n\t}\n\n\tprivate async initialize(): Promise<void> {\n\t\tif (this.initializePromise) {\n\t\t\treturn(await this.initializePromise);\n\t\t}\n\n\t\t/* Ensure the sequential lock entry exists */\n\t\tthis.initializePromise = (async () => {\n\t\t\t/*\n\t\t\t * We store `null` as the request value because we\n\t\t\t * don't have anything better to store -- it's not\n\t\t\t * always going to be compatible with the type\n\t\t\t * QueueRequest but we know that we will never actually\n\t\t\t * use the value.\n\t\t\t */\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tawait this.queue.add(null as unknown as QueueRequest, {\n\t\t\t\tid: this.runnerLockKey,\n\t\t\t\tstatus: '@internal'\n\t\t\t});\n\t\t})();\n\n\t\treturn(await this.initializePromise);\n\t}\n\n\tprivate methodLogger(method: string): Logger | undefined {\n\t\treturn(MethodLogger(this.logger, {\n\t\t\tclass: 'KeetaAnchorQueueRunner',\n\t\t\tfile: 'src/lib/queue/index.ts',\n\t\t\tmethod: method,\n\t\t\tinstanceID: this.id\n\t\t}));\n\t}\n\n\t/** @internal */\n\t_Testing(key: string): {\n\t\tsetParams: (maxBatchSize: number, processTimeout: number, maxRetries: number, maxWorkers?: number) => void;\n\t\tqueue: () => KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>;\n\t\tmarkWorkerAsProcessing: () => Promise<void>;\n\t} {\n\t\tif (key !== 'bc81abf8-e43b-490b-b486-744fb49a5082') {\n\t\t\tthrow(new Error('This is a testing only method'));\n\t\t}\n\n\t\treturn({\n\t\t\tsetParams: (maxBatchSize: number, processTimeout: number, maxRetries: number, maxWorkers?: number) => {\n\t\t\t\tthis.batchSize = maxBatchSize;\n\t\t\t\tthis.processTimeout = processTimeout;\n\t\t\t\tthis.maxRetries = maxRetries;\n\t\t\t\tif (maxWorkers !== undefined) {\n\t\t\t\t\tthis.maxRunners = maxWorkers;\n\t\t\t\t}\n\t\t\t},\n\t\t\tqueue: () => {\n\t\t\t\treturn(this.queue);\n\t\t\t},\n\t\t\tmarkWorkerAsProcessing: async () => {\n\t\t\t\tawait this.queue.setStatus(this.runnerLockKey, 'processing', {\n\t\t\t\t\toldStatus: '@internal',\n\t\t\t\t\tby: this.workerID\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected abstract decodeRequest(request: QueueRequest): UserRequest;\n\tprotected abstract decodeResponse(response: QueueResult | null): UserResult | null;\n\n\tprotected abstract encodeRequest(request: UserRequest): QueueRequest;\n\tprotected abstract encodeResponse(response: UserResult | null): QueueResult | null;\n\n\tprotected decodeEntry(entry: KeetaAnchorQueueEntry<QueueRequest, QueueResult>): KeetaAnchorQueueEntry<UserRequest, UserResult> {\n\t\treturn({\n\t\t\t...entry,\n\t\t\trequest: this.decodeRequest(entry.request),\n\t\t\toutput: this.decodeResponse(entry.output)\n\t\t});\n\t}\n\n\t/**\n\t * Enqueue an item to be processed by the queue\n\t */\n\tasync add(request: UserRequest, info?: KeetaAnchorQueueEntryExtra): Promise<KeetaAnchorQueueRequestID> {\n\t\tawait this.initialize();\n\n\t\tconst encodedRequest = this.encodeRequest(request);\n\t\tconst newID = await this.queue.add(encodedRequest, info);\n\t\treturn(newID);\n\t}\n\n\t/**\n\t * Get a single entry from storage by ID\n\t */\n\tasync get(id: KeetaAnchorQueueRequestID): Promise<KeetaAnchorQueueEntry<UserRequest, UserResult> | null> {\n\t\tawait this.initialize();\n\n\t\tconst entry = await this.queue.get(id);\n\t\tif (!entry) {\n\t\t\treturn(null);\n\t\t}\n\n\t\treturn(this.decodeEntry(entry));\n\t}\n\n\t/**\n\t * Get entries from storage with an optional filter\n\t */\n\tasync query(filter?: KeetaAnchorQueueFilter): Promise<KeetaAnchorQueueEntry<UserRequest, UserResult>[]> {\n\t\tawait this.initialize();\n\n\t\tconst entries = await this.queue.query(filter);\n\t\treturn(entries.map((entry) => {\n\t\t\treturn(this.decodeEntry(entry));\n\t\t}));\n\t}\n\n\t/**\n\t * Set the status of an entry in the queue\n\t */\n\tasync setStatus(id: KeetaAnchorQueueRequestID, status: KeetaAnchorQueueStatus, ancillary?: KeetaAnchorQueueEntryAncillaryData<UserResult>): Promise<void> {\n\t\tawait this.initialize();\n\n\t\tlet encodedOutput: QueueResult | null | undefined = undefined;\n\t\tif (ancillary?.output !== undefined) {\n\t\t\tencodedOutput = this.encodeResponse(ancillary.output);\n\t\t}\n\n\t\treturn(await this.queue.setStatus(id, status, {\n\t\t\t...ancillary,\n\t\t\toutput: encodedOutput\n\t\t}));\n\t}\n\n\t/**\n\t * Checks to see if the queue is runnable\n\t */\n\tasync runnable(): Promise<boolean> {\n\t\tawait this.initialize();\n\n\t\tconst pendingEntries = await this.queue.query({ status: 'pending', limit: 1 });\n\t\tif (pendingEntries.length > 0) {\n\t\t\treturn(true);\n\t\t}\n\n\t\tfor (const pipe of this.pipes) {\n\t\t\tconst pipeRunnable = await pipe.target.runnable();\n\t\t\tif (pipeRunnable) {\n\t\t\t\treturn(true);\n\t\t\t}\n\t\t}\n\n\t\treturn(false);\n\t}\n\n\tprivate async updateRunnerLockTimestamp(): Promise<void> {\n\t\tconst logger = this.methodLogger('updateRunnerLockTimestamp');\n\n\t\ttry {\n\t\t\tlogger?.debug('Updating sequential processing lock timestamp for worker ID', this.workerID);\n\t\t\tawait this.queue.setStatus(this.runnerLockKey, 'processing', {\n\t\t\t\toldStatus: 'processing',\n\t\t\t\tby: this.workerID\n\t\t\t});\n\t\t\tlogger?.debug('Updated sequential processing lock timestamp for worker ID', this.workerID);\n\t\t} catch (error: unknown) {\n\t\t\tlogger?.error('Failed to update sequential processing lock timestamp for worker ID', this.workerID, ':', error);\n\t\t\tthrow(error);\n\t\t}\n\t}\n\n\tprivate async getRunnerLock(cleanup: InstanceType<typeof AsyncDisposableStack>): Promise<boolean> {\n\t\tconst logger = this.methodLogger('getRunnerLock');\n\n\t\ttry {\n\t\t\tlogger?.debug('Acquiring sequential processing lock for worker ID', this.workerID);\n\t\t\tawait this.queue.setStatus(this.runnerLockKey, 'processing', {\n\t\t\t\toldStatus: '@internal',\n\t\t\t\tby: this.workerID\n\t\t\t});\n\t\t\tlogger?.debug('Acquired sequential processing lock for worker ID', this.workerID);\n\t\t} catch (error: unknown) {\n\t\t\tif (Errors.IncorrectStateAssertedError.isInstance(error)) {\n\t\t\t\treturn(false);\n\t\t\t}\n\n\t\t\tthrow(error);\n\t\t}\n\n\t\tcleanup.defer(async () => {\n\t\t\tfor (let retry = 0; retry < 10; retry++) {\n\t\t\t\tlogger?.debug(`Releasing sequential processing lock try #${retry + 1} for worker ID`, this.workerID);\n\t\t\t\ttry {\n\t\t\t\t\tawait this.queue.setStatus(this.runnerLockKey, '@internal', {\n\t\t\t\t\t\toldStatus: 'processing',\n\t\t\t\t\t\tby: undefined\n\t\t\t\t\t});\n\t\t\t\t} catch {\n\t\t\t\t\tawait asleep(1000);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\treturn(true);\n\t}\n\n\tprivate async maintainRunnerLock(): Promise<void> {\n\t\tconst logger = this.methodLogger('maintainRunnerLock');\n\t\tconst moment = new Date();\n\t\tawait using cleanup = new AsyncDisposableStack();\n\n\t\tconst obtained = await this.getRunnerLock(cleanup);\n\t\tif (obtained) {\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Check to see if the lock is stale\n\t\t */\n\t\tconst lockEntry = await this.queue.get(this.runnerLockKey);\n\n\t\tif (!lockEntry) {\n\t\t\treturn;\n\t\t}\n\t\tconst lockAge = moment.getTime() - lockEntry.updated.getTime();\n\t\tif (lockAge > this.processTimeout * this.stuckMultiplier) {\n\t\t\tlogger?.warn('Processing lock is stale, taking over lock for worker ID', this.workerID);\n\n\t\t\tawait this.queue.setStatus(this.runnerLockKey, '@internal', {\n\t\t\t\toldStatus: 'processing',\n\t\t\t\tby: this.workerID\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Run the queue processor\n\t *\n\t * Processes up to `batchSize` entries from the queue and returns\n\t * true if there may be more work to do, or false if the queue\n\t * is empty.\n\t *\n\t * @param options Optional run options\n\t */\n\tasync run(options?: KeetaAnchorQueueRunOptions): Promise<boolean> {\n\t\tconst timeout = options?.timeoutMs;\n\n\t\tawait this.initialize();\n\n\t\tconst logger = this.methodLogger('run');\n\t\tconst batchSize = this.batchSize;\n\t\tconst processTimeout = this.processTimeout;\n\t\tawait using cleanup = new AsyncDisposableStack();\n\n\t\tlet retval = true;\n\n\t\tconst startTime = Date.now();\n\n\t\tconst locked = await this.getRunnerLock(cleanup);\n\t\tif (!locked) {\n\t\t\tlogger?.debug('Another worker is already processing the queue, skipping run');\n\n\t\t\treturn(true);\n\t\t}\n\n\t\tconst processJobOk = Symbol('processJobOk');\n\t\tconst processJobTimeout = Symbol('processJobTimeout');\n\n\t\tconst processJob = async (index: number, entry: KeetaAnchorQueueEntry<QueueRequest, QueueResult>, startingStatus: KeetaAnchorQueueStatus, processor: (entry: KeetaAnchorQueueEntry<UserRequest, UserResult>) => Promise<{ status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; }>): Promise<typeof processJobTimeout | typeof processJobOk> => {\n\t\t\tif (timeout !== undefined) {\n\t\t\t\tconst elapsed = Date.now() - startTime;\n\t\t\t\tif (elapsed >= timeout) {\n\t\t\t\t\tlogger?.debug(`Timeout of ${timeout}ms reached after processing ${index} entries (${startingStatus} phase; elapsed ${elapsed}ms)`);\n\n\t\t\t\t\treturn(processJobTimeout);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait this.updateRunnerLockTimestamp();\n\n\t\t\tlet setEntryStatus: { status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; } = { status: 'failed_temporarily', output: null };\n\n\t\t\tlogger?.debug(`Processing entry request with id ${String(entry.id)}`);\n\n\t\t\ttry {\n\t\t\t\t/*\n\t\t\t\t * Get a lock by setting it to 'processing'\n\t\t\t\t */\n\t\t\t\tawait this.queue.setStatus(entry.id, 'processing', { oldStatus: startingStatus, by: this.workerID });\n\n\t\t\t\t/*\n\t\t\t\t * Process the entry with a timeout, if the timeout is reached\n\t\t\t\t * we should mark the process as aborted because we no longer\n\t\t\t\t * know what state the work is in and someone will need to\n\t\t\t\t * inspect the job and determine through some other means if\n\t\t\t\t * it is completed or failed.\n\t\t\t\t */\n\t\t\t\tlet timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n\t\t\t\tsetEntryStatus = await Promise.race([\n\t\t\t\t\tnew Promise<{ status: 'aborted', output: null }>(function(resolve) {\n\t\t\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\t\t\tresolve({ status: 'aborted', output: null });\n\t\t\t\t\t\t}, processTimeout);\n\t\t\t\t\t}),\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn(await processor(this.decodeEntry(entry)));\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tif (timeoutTimer) {\n\t\t\t\t\t\t\t\tclearTimeout(timeoutTimer);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})()\n\t\t\t\t]);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tif (Errors.IncorrectStateAssertedError.isInstance(error)) {\n\t\t\t\t\tlogger?.info(`Skipping request with id ${String(entry.id)} because it is no longer in the expected state \"${startingStatus}\"`, error);\n\n\t\t\t\t\treturn(processJobOk);\n\t\t\t\t}\n\n\t\t\t\tlogger?.error(`Failed to process request with id ${String(entry.id)}, setting state to \"${setEntryStatus.status}\":`, error);\n\t\t\t\tsetEntryStatus.status = 'failed_temporarily';\n\t\t\t\tsetEntryStatus.error = String(error);\n\t\t\t}\n\n\t\t\tif (setEntryStatus.status === 'processing') {\n\t\t\t\tlogger?.error(`Processor for request with id ${String(entry.id)} returned invalid status \"processing\"`);\n\t\t\t\tsetEntryStatus.status = 'failed_temporarily';\n\t\t\t\tsetEntryStatus.error = 'Processor returned invalid status \"processing\"';\n\t\t\t}\n\n\t\t\tlet by: KeetaAnchorQueueWorkerID | undefined = this.workerID;\n\t\t\tif (setEntryStatus.status === 'pending') {\n\t\t\t\tby = undefined;\n\t\t\t}\n\n\t\t\tawait this.queue.setStatus(entry.id, setEntryStatus.status, { oldStatus: 'processing', by: by, output: this.encodeResponse(setEntryStatus.output), error: setEntryStatus.error });\n\n\t\t\treturn(processJobOk);\n\t\t};\n\n\t\t/*\n\t\t * Process pending jobs first\n\t\t */\n\t\tfor (let index = 0; index < batchSize; index++) {\n\t\t\tconst entries = await this.queue.query({ status: 'pending', limit: 1 });\n\t\t\tconst entry = entries[0];\n\t\t\tif (entry === undefined) {\n\t\t\t\tretval = false;\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst result = await processJob(index, entry, 'pending', this.processor.bind(this));\n\t\t\tif (result === processJobTimeout) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * Next process any pipes to other runners\n\t\t */\n\t\tconst pipes = [...this.pipes];\n\t\tfor (const pipe of pipes) {\n\t\t\tlet remainingTime: number | undefined = undefined;\n\t\t\tif (timeout !== undefined) {\n\t\t\t\tconst elapsed = Date.now() - startTime;\n\t\t\t\tremainingTime = timeout - elapsed;\n\t\t\t\tif (remainingTime <= 0) {\n\t\t\t\t\tremainingTime = -1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pipeHasMoreWork = await pipe.target.run({\n\t\t\t\t...options,\n\t\t\t\ttimeoutMs: remainingTime\n\t\t\t});\n\n\t\t\tif (pipeHasMoreWork) {\n\t\t\t\tretval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Process stuck or aborted jobs (if possible)\n\t\t */\n\t\tconst conditions = [{\n\t\t\tstatus: 'aborted' as const,\n\t\t\tprocessor: this.processorAborted?.bind(this)\n\t\t}, {\n\t\t\tstatus: 'stuck' as const,\n\t\t\tprocessor: this.processorStuck?.bind(this)\n\t\t}];\n\n\t\tlet timeoutReached = false;\n\t\tfor (const condition of conditions) {\n\t\t\tif (condition.processor === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (let index = 0; index < batchSize; index++) {\n\t\t\t\tconst entries = await this.queue.query({ status: condition.status, limit: 1 });\n\t\t\t\tconst entry = entries[0];\n\t\t\t\tif (entry === undefined) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst result = await processJob(index, entry, condition.status, condition.processor);\n\t\t\t\tif (result === processJobTimeout) {\n\t\t\t\t\ttimeoutReached = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (timeoutReached) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn(retval);\n\t}\n\n\tprivate async markStuckRequestsAsStuck(): Promise<void> {\n\t\tconst stuckThreshold = this.processTimeout * this.stuckMultiplier;\n\n\t\tconst logger = this.methodLogger('markStuckRequestsAsStuck');\n\t\tconst now = Date.now();\n\n\t\tconst requests = await this.queue.query({ status: 'processing', limit: 100, updatedBefore: new Date(now - stuckThreshold) });\n\t\tfor (const request of requests) {\n\t\t\t/*\n\t\t\t * Skip the runner lock entries, they are managed separately\n\t\t\t */\n\t\t\tif (request.id.toString().startsWith('@runner-lock:9ba756f0-7aa2-41c7-a1ea-b010dc752ae8.worker.')) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tlogger?.warn(`Marking request with id ${String(request.id)} as stuck`);\n\n\t\t\t\tawait this.queue.setStatus(request.id, 'stuck', { oldStatus: 'processing', by: this.workerID });\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.error(`Failed to mark request with id ${String(request.id)} as stuck:`, error);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async requeueFailedRequests(): Promise<void> {\n\t\tconst retryDelay = this.retryDelay;\n\t\tconst maxRetries = this.maxRetries;\n\n\t\tconst logger = this.methodLogger('requeueFailedRequests');\n\t\tconst now = Date.now();\n\n\t\tconst requests = await this.queue.query({ status: 'failed_temporarily', limit: 100, updatedBefore: new Date(now - retryDelay) });\n\t\tfor (const request of requests) {\n\t\t\ttry {\n\t\t\t\tif (request.failures >= maxRetries) {\n\t\t\t\t\tlogger?.info(`Request with id ${String(request.id)} has exceeded maximum retries, not requeuing -- moving to failed_permanently`);\n\t\t\t\t\tawait this.queue.setStatus(request.id, 'failed_permanently', { oldStatus: 'failed_temporarily', by: this.workerID });\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tlogger?.debug(`Requeuing failed request with id ${String(request.id)}`);\n\n\t\t\t\tawait this.queue.setStatus(request.id, 'pending', { oldStatus: 'failed_temporarily', by: this.workerID });\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.error(`Failed to requeue request with id ${String(request.id)}:`, error);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async moveCompletedToNextStage(statusTarget: KeetaAnchorPipeableQueueStatus): Promise<void> {\n\t\tconst logger = this.methodLogger('moveCompletedToNextStage');\n\n\t\tconst pipes = [...this.pipes].filter(function(pipe) {\n\t\t\treturn(pipe.acceptStatus === statusTarget);\n\t\t});\n\n\t\tif (pipes.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst allRequests = await this.queue.query({ status: statusTarget, limit: 100 });\n\t\tlet requests = allRequests;\n\n\t\tconst RequestSentToPipes = new Map<KeetaAnchorQueueRequestID, number>();\n\t\tfunction IncrRequestSentToPipes(requestID: KeetaAnchorQueueRequestID): void {\n\t\t\tconst sentCount = RequestSentToPipes.get(requestID) ?? 0;\n\t\t\tRequestSentToPipes.set(requestID, sentCount + 1);\n\t\t}\n\n\n\t\tfor (const pipe of pipes) {\n\t\t\tlogger?.debug('Processing pipe to target', pipe.target.id, pipe.isBatchPipe ? '(batch pipe)' : '(single item pipe)');\n\n\t\t\tif (pipe.isBatchPipe) {\n\t\t\t\t/**\n\t\t\t\t * Keep track of all the requests we successfully\n\t\t\t\t * sent to the target stage\n\t\t\t\t */\n\t\t\t\tconst allTargetSeenRequestIDs = new Set<KeetaAnchorQueueRequestID>();\n\n\t\t\t\t/**\n\t\t\t\t * During each iteration of the batch processing, we keep track\n\t\t\t\t * of the IDs we have already seen by the target and processed\n\t\t\t\t * so we don't try to reprocess them again\n\t\t\t\t */\n\t\t\t\tconst iterationTargetSeenRequestIDs = new Set<KeetaAnchorQueueRequestID>();\n\n\t\t\t\t/**\n\t\t\t\t * If we get a batch that cannot be added to the target pipe,\n\t\t\t\t * we just skip over them for retrying at a later date\n\t\t\t\t */\n\t\t\t\tconst skipRequestIDs = new Set<KeetaAnchorQueueRequestID>();\n\n\t\t\t\t/**\n\t\t\t\t * Compute a durable ID for this batch and target\n\t\t\t\t */\n\t\t\t\tlet batchID = ConvertStringToRequestID(crypto.randomUUID());\n\n\t\t\t\t/**\n\t\t\t\t * Keep track of sequential failures to find enough entries\n\t\t\t\t * and stop processing if we can't find enough after a few tries\n\t\t\t\t * in a row\n\t\t\t\t */\n\t\t\t\tlet sequentialFailureCount = 0;\n\n\t\t\t\tfor (;requests.length >= pipe.minBatchSize;\n\t\t\t\t\t/*\n\t\t\t\t\t * Remove any entries we have already seen during\n\t\t\t\t\t * the last iteration of the loop\n\t\t\t\t\t */\n\t\t\t\t\trequests = requests.filter(function(entry) {\n\t\t\t\t\t\treturn(!iterationTargetSeenRequestIDs.has(entry.id) && !skipRequestIDs.has(entry.id));\n\t\t\t\t\t})\n\t\t\t\t) {\n\t\t\t\t\titerationTargetSeenRequestIDs.clear();\n\n\t\t\t\t\tlogger?.debug(`Preparing to move ${statusTarget} requests to next stage ${pipe.target.id} (min=${pipe.minBatchSize}, max=${pipe.maxBatchSize}), have ${requests.length} ${statusTarget} requests available`);\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Compute a batch of entries to send to the next stage,\n\t\t\t\t\t * constrained to the max batch size of the pipe and\n\t\t\t\t\t * the entries which have non-null outputs\n\t\t\t\t\t */\n\t\t\t\t\tconst batchRaw = requests.map((entry) => {\n\t\t\t\t\t\treturn({ output: this.decodeResponse(entry.output), id: entry.id });\n\t\t\t\t\t}).filter(function(entry): entry is { output: UserResult; id: KeetaAnchorQueueRequestID; } {\n\t\t\t\t\t\tif (entry === null) {\n\t\t\t\t\t\t\treturn(false);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn(true);\n\t\t\t\t\t}).slice(0, pipe.maxBatchSize);\n\n\t\t\t\t\t/*\n\t\t\t\t\t * If we don't have enough entries to meet the minimum\n\t\t\t\t\t * batch size, skip this iteration\n\t\t\t\t\t */\n\t\t\t\t\tif (batchRaw.length < pipe.minBatchSize) {\n\t\t\t\t\t\tsequentialFailureCount++;\n\t\t\t\t\t\tif (sequentialFailureCount >= 3) {\n\t\t\t\t\t\t\tlogger?.debug(`Not enough ${statusTarget} requests to move to next stage ${pipe.target.id}, stopping batch processing`);\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlogger?.debug(`Not moving ${statusTarget} requests to next stage ${pipe.target.id} because batch size ${batchRaw.length} is less than minimum size ${pipe.minBatchSize}`);\n\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tsequentialFailureCount = 0;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * The IDs for the entries we are sending to the next stage\n\t\t\t\t\t * target -- this may get reduced if we find there are already\n\t\t\t\t\t * jobs in the next stage that have the idempotentIDs of one of\n\t\t\t\t\t * these jobs\n\t\t\t\t\t */\n\t\t\t\t\tconst batchLocalIDs = new Set(batchRaw.map(function(entry) {\n\t\t\t\t\t\treturn(entry.id);\n\t\t\t\t\t}));\n\t\t\t\t\t/**\n\t\t\t\t\t * The outputs for the batch we are sending to the next stage\n\t\t\t\t\t */\n\t\t\t\t\tconst batchOutput = batchRaw.map(function(entry) {\n\t\t\t\t\t\treturn(entry.output);\n\t\t\t\t\t});\n\n\t\t\t\t\tlogger?.debug(`Moving batch of ${batchOutput.length} ${statusTarget} requests to next pipe`, pipe.target.id, '(input entry IDs:', Array.from(batchLocalIDs), '->', `${pipe.target.id}:${String(batchID)})`);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait pipe.target.add(batchOutput, {\n\t\t\t\t\t\t\tid: batchID,\n\t\t\t\t\t\t\t/* Use the set of IDs as the idempotent IDs for the batch */\n\t\t\t\t\t\t\tidempotentKeys: batchLocalIDs\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tbatchID = ConvertStringToRequestID(crypto.randomUUID());\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (Errors.IdempotentExistsError.isInstance(error) && error.idempotentIDsFound) {\n\t\t\t\t\t\t\tlogger?.debug('Some of the jobs have already been added to the target queue, skipping those:', error.idempotentIDsFound.values());\n\t\t\t\t\t\t\tfor (const requestID of error.idempotentIDsFound) {\n\t\t\t\t\t\t\t\titerationTargetSeenRequestIDs.add(requestID);\n\t\t\t\t\t\t\t\tallTargetSeenRequestIDs.add(requestID);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * If we got some kind of other error adding these\n\t\t\t\t\t\t\t * items to the target queue runner, just skip them\n\t\t\t\t\t\t\t * and we will retry them on the next iteration\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tlogger?.error(`Failed to move completed batch to next stage ${pipe.target.id}, will try to create another batch without them:`, error);\n\n\t\t\t\t\t\t\tfor (const requestID of batchLocalIDs) {\n\t\t\t\t\t\t\t\tskipRequestIDs.add(requestID);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const requestID of batchLocalIDs) {\n\t\t\t\t\t\titerationTargetSeenRequestIDs.add(requestID);\n\t\t\t\t\t\tallTargetSeenRequestIDs.add(requestID);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/*\n\t\t\t\t * For every request we know the target has definitely seen, mark it\n\t\t\t\t * as moved for this pipe\n\t\t\t\t */\n\t\t\t\tfor (const requestID of allTargetSeenRequestIDs) {\n\t\t\t\t\tIncrRequestSentToPipes(requestID);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const request of requests) {\n\t\t\t\t\tlet shouldMarkAsMoved = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst output = this.decodeResponse(request.output);\n\t\t\t\t\t\tif (output === null) {\n\t\t\t\t\t\t\tlogger?.debug(`Completed request with id ${String(request.id)} has no output -- next stage will not be run`);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlogger?.debug(`Moving ${statusTarget} request with id ${String(request.id)} to next pipe`, pipe.target.id);\n\t\t\t\t\t\t\tawait pipe.target.add(output, { id: request.id });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tlogger?.error(`Failed to move completed request with id ${String(request.id)} to next stage:`, error);\n\t\t\t\t\t\tshouldMarkAsMoved = false;\n\t\t\t\t\t}\n\t\t\t\t\tif (shouldMarkAsMoved) {\n\t\t\t\t\t\tIncrRequestSentToPipes(request.id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst TotalPipes = pipes.length;\n\t\tfor (const request of allRequests) {\n\t\t\tconst sentCount = RequestSentToPipes.get(request.id) ?? 0;\n\t\t\tif (sentCount !== TotalPipes) {\n\t\t\t\tlogger?.debug(`${statusTarget} request with id ${String(request.id)} was only moved to ${sentCount} out of ${TotalPipes} pipes -- not marking as moved`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlogger?.debug(`Marking ${statusTarget} request with id ${String(request.id)} as moved`);\n\n\t\t\tawait this.queue.setStatus(request.id, 'moved', { oldStatus: statusTarget, by: this.workerID });\n\t\t}\n\n\t}\n\n\tasync maintain(): Promise<void> {\n\t\tconst logger = this.methodLogger('maintain');\n\n\t\tawait this.initialize();\n\n\t\t/*\n\t\t * Each worker should maintain its own lock\n\t\t */\n\t\ttry {\n\t\t\tawait this.maintainRunnerLock();\n\t\t} catch (error: unknown) {\n\t\t\tlogger?.debug('Failed to maintain runner lock:', error);\n\t\t}\n\n\t\tif (this.workers.id !== 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t/*\n\t\t * Only the worker with ID 0 should perform maintenance tasks on requests\n\t\t */\n\t\ttry {\n\t\t\tawait this.markStuckRequestsAsStuck();\n\t\t} catch (error: unknown) {\n\t\t\tlogger?.debug('Failed to mark stuck requests as stuck:', error);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.requeueFailedRequests();\n\t\t} catch (error: unknown) {\n\t\t\tlogger?.debug('Failed to requeue failed requests:', error);\n\t\t}\n\n\t\tfor (const pipeStatus of keetaAnchorPipeableQueueStatuses) {\n\t\t\ttry {\n\t\t\t\tawait this.moveCompletedToNextStage(pipeStatus);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.debug(`Failed to move ${pipeStatus} requests to next stage:`, error);\n\t\t\t}\n\t\t}\n\n\t\tfor (const pipe of this.pipes) {\n\t\t\ttry {\n\t\t\t\tawait pipe.target.maintain();\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.debug(`Failed to maintain piped runner with ID ${pipe.target.id}:`, error);\n\t\t\t}\n\t\t}\n\n\t\tif (this.queue.maintain) {\n\t\t\ttry {\n\t\t\t\tawait this.queue.maintain();\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.debug(`Failed to maintain queue storage driver with ID ${this.queue.id}`, error);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Pipe the the completed entries of this runner to another runner\n\t */\n\tpipe<T1, T2 extends JSONSerializable>(target: KeetaAnchorQueueRunner<UserResult, T1, QueueResult, T2>): typeof target {\n\t\tthis.pipes.push({\n\t\t\tisBatchPipe: false,\n\t\t\ttarget: target,\n\t\t\tacceptStatus: 'completed'\n\t\t});\n\t\treturn(target);\n\t}\n\n\tpipeFailed<T1, T2 extends JSONSerializable>(target: KeetaAnchorQueueRunner<UserResult, T1, QueueResult, T2>): typeof target {\n\t\tthis.pipes.push({\n\t\t\tisBatchPipe: false,\n\t\t\ttarget: target,\n\t\t\tacceptStatus: 'failed_permanently'\n\t\t});\n\t\treturn(target);\n\t}\n\n\t/**\n\t * Pipe batches of completed entries from this runner to another runner\n\t */\n\tpipeBatch<T1, T2 extends JSONSerializable>(target: KeetaAnchorQueueRunner<UserResult[], T1, JSONSerializable, T2>, maxBatchSize = 100, minBatchSize = 1): typeof target {\n\t\tthis.pipes.push({\n\t\t\tisBatchPipe: true,\n\t\t\ttarget: target,\n\t\t\tminBatchSize: minBatchSize,\n\t\t\tmaxBatchSize: maxBatchSize,\n\t\t\tacceptStatus: 'completed'\n\t\t});\n\t\treturn(target);\n\t}\n\n\tpipeBatchFailed<T1, T2 extends JSONSerializable>(target: KeetaAnchorQueueRunner<UserResult[], T1, JSONSerializable, T2>, maxBatchSize = 100, minBatchSize = 1): typeof target {\n\t\tthis.pipes.push({\n\t\t\tisBatchPipe: true,\n\t\t\ttarget: target,\n\t\t\tminBatchSize: minBatchSize,\n\t\t\tmaxBatchSize: maxBatchSize,\n\t\t\tacceptStatus: 'failed_permanently'\n\t\t});\n\t\treturn(target);\n\t}\n\n\tasync destroy(): Promise<void> {\n\t\tthis.methodLogger('destroy')?.debug('Destroying queue runner attached to queue', this.queue.id);\n\t}\n\n\tasync [Symbol.asyncDispose](): Promise<void> {\n\t\tawait this.destroy();\n\t}\n}\n\n/**\n * A KeetaAnchorQueueRunner for use when you want to process already\n * JSON-serializable data without any encoding/decoding needed\n */\nexport abstract class KeetaAnchorQueueRunnerJSON<UserRequest extends JSONSerializable = JSONSerializable, UserResult extends JSONSerializable = JSONSerializable> extends KeetaAnchorQueueRunner<UserRequest, UserResult, JSONSerializable, JSONSerializable> {\n\tprotected decodeRequest(request: JSONSerializable): UserRequest {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn(request as UserRequest);\n\t}\n\n\tprotected decodeResponse(response: JSONSerializable | null): UserResult | null {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn(response as UserResult | null);\n\t}\n\n\tprotected encodeRequest(request: JSONSerializable): JSONSerializable {\n\t\treturn(request);\n\t}\n\n\tprotected encodeResponse(response: JSONSerializable | null): JSONSerializable | null {\n\t\treturn(response);\n\t}\n}\n\n/**\n * A KeetaAnchorQueueRunnerJSON that takes a processor function\n * in the constructor -- this is mainly useful for testing\n */\nexport class KeetaAnchorQueueRunnerJSONConfigProc<UserRequest extends JSONSerializable = JSONSerializable, UserResult extends JSONSerializable = JSONSerializable> extends KeetaAnchorQueueRunnerJSON<UserRequest, UserResult> {\n\tprotected readonly processor: KeetaAnchorQueueRunner<UserRequest, UserResult>['processor'];\n\n\tconstructor(config: ConstructorParameters<typeof KeetaAnchorQueueRunner>[0] & {\n\t\tprocessor: KeetaAnchorQueueRunner<UserRequest, UserResult>['processor'];\n\t\tprocessorStuck?: KeetaAnchorQueueRunner<UserRequest, UserResult>['processorStuck'] | undefined;\n\t\tprocessorAborted?: KeetaAnchorQueueRunner<UserRequest, UserResult>['processorAborted'] | undefined;\n\t}) {\n\t\tsuper(config);\n\t\tthis.processor = config.processor;\n\t\tif (config.processorStuck) {\n\t\t\tthis.processorStuck = config.processorStuck;\n\t\t}\n\t\tif (config.processorAborted) {\n\t\t\tthis.processorAborted = config.processorAborted;\n\t\t}\n\t}\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype _ignore_static_assert_memory = AssertNever<typeof KeetaAnchorQueueStorageDriverMemory<{ a: string; }, number> extends KeetaAnchorQueueStorageDriverConstructor<{ a: string; }, number> ? never : false>;\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/queue/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BrandedString, Brand } from '../utils/brand.ts';\nimport type { Logger } from '../log/index.ts';\nimport type { JSONSerializable } from '../utils/json.ts';\nimport { assertNever } from '../utils/never.js';\nimport type { AssertNever } from '../utils/never.ts';\nimport type { KeetaAnchorQueueRunOptions } from './common.js';\nimport { asleep } from '../utils/asleep.js';\nimport { Errors } from './common.js';\nimport {\n\tMethodLogger,\n\tManageStatusUpdates,\n\tConvertStringToRequestID\n} from './internal.js';\nimport { AsyncDisposableStack } from '../utils/defer.js';\n\nexport type KeetaAnchorQueueRequest<QueueRequest> = QueueRequest;\nexport type KeetaAnchorQueueRequestID = BrandedString<'KeetaAnchorQueueID'>;\nexport type KeetaAnchorQueueWorkerID = Brand<number, 'KeetaAnchorQueueWorkerID'>;\n\nexport type KeetaAnchorQueueStatus = 'pending' | 'processing' | 'completed' | 'failed_temporarily' | 'failed_permanently' | 'stuck' | 'aborted' | 'moved' | '@internal';\nconst keetaAnchorPipeableQueueStatuses = [ 'completed', 'failed_permanently' ] as const;\n/**\n * This is a type-level assertion to ensure that all values in keetaAnchorPipeableQueueStatuses are valid KeetaAnchorQueueStatus values.\n * If this assertion fails, it means that there is a value in keetaAnchorPipeableQueueStatuses that is not a valid KeetaAnchorQueueStatus, and the code will not compile.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype __check_keetaAnchorPipeableQueueStatuses_valid = AssertNever<typeof keetaAnchorPipeableQueueStatuses[number] extends KeetaAnchorQueueStatus ? never : true>;\n\nexport type KeetaAnchorPipeableQueueStatus = Extract<KeetaAnchorQueueStatus, typeof keetaAnchorPipeableQueueStatuses[number]>;\nexport type KeetaAnchorQueueEntry<QueueRequest, QueueResult> = {\n\t/**\n\t * The Job ID\n\t */\n\tid: KeetaAnchorQueueRequestID;\n\t/**\n\t * Idempotent IDs from a previous stage\n\t */\n\tidempotentKeys?: Set<KeetaAnchorQueueRequestID> | undefined;\n\trequest: KeetaAnchorQueueRequest<QueueRequest>;\n\toutput: QueueResult | null;\n\tlastError: string | null;\n\tstatus: KeetaAnchorQueueStatus;\n\tcreated: Date;\n\tupdated: Date;\n\tworker: KeetaAnchorQueueWorkerID | null;\n\tfailures: number;\n};\n\n/**\n * Extra information to provide to a request when adding an entry to the queue\n */\nexport type KeetaAnchorQueueEntryExtra = {\n\t[key in 'idempotentKeys' | 'id' | 'status']?: (key extends 'id' ? KeetaAnchorQueueRequestID | string : KeetaAnchorQueueEntry<never, never>[key]) | undefined;\n};\n\nexport type KeetaAnchorQueueFilter = {\n\t/**\n\t * Only return entries with this status\n\t */\n\tstatus?: KeetaAnchorQueueStatus;\n\t/**\n\t * Only return entries last updated before this date\n\t */\n\tupdatedBefore?: Date;\n\t/**\n\t * Limit the number of entries returned\n\t */\n\tlimit?: number;\n};\n\nexport type KeetaAnchorQueueCommonOptions = {\n\tlogger?: Logger | undefined;\n\tid?: string | undefined;\n};\n\nexport type KeetaAnchorQueueRunnerOptions = KeetaAnchorQueueCommonOptions & {\n\t/**\n\t * If specified, then multiple workers can be used to process this queue\n\t * in parallel by splitting the work among the workers.\n\t *\n\t * By default, only a single worker will process the queue (count=1, id=0)\n\t */\n\tworkers?: {\n\t\tcount: number;\n\t\tid: number;\n\t} | undefined;\n};\n\nexport type KeetaAnchorQueueStorageOptions = KeetaAnchorQueueCommonOptions & {\n\tpath?: string[] | undefined;\n};\n\nexport type KeetaAnchorQueueEntryAncillaryData<QueueResult> = {\n\t/**\n\t * The previous status of the entry -- if the entry is not currently in this status,\n\t * the status update will fail\n\t */\n\toldStatus?: KeetaAnchorQueueStatus | undefined;\n\t/**\n\t * The worker ID performing the status update\n\t */\n\tby?: KeetaAnchorQueueWorkerID | undefined;\n\t/**\n\t * The output data to store with the entry\n\t */\n\toutput?: QueueResult | null | undefined;\n\t/**\n\t * An error message to store with the entry\n\t */\n\terror?: string | undefined;\n};\n\nexport type KeetaAnchorQueueStorageDriverConstructor<QueueRequest extends JSONSerializable, QueueResult extends JSONSerializable> = new(options?: KeetaAnchorQueueStorageOptions) => KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>;\n\nexport interface KeetaAnchorQueueStorageDriver<QueueRequest extends JSONSerializable, QueueResult extends JSONSerializable> {\n\t/**\n\t * An ID for this instance of the storage driver\n\t */\n\treadonly id: string;\n\n\t/**\n\t * The name of the storage driver\n\t */\n\treadonly name: string;\n\n\t/**\n\t * The partition ID for this instance of the storage driver\n\t *\n\t * This is used to divide a single storage backend into multiple\n\t * independent queues.\n\t *\n\t * The root partition is an empty array, and each element is\n\t * a hierarchical partition name.\n\t */\n\treadonly path: string[];\n\n\t/**\n\t * Enqueue an item to be processed by the queue\n\t *\n\t * It will be inserted into the queue as a 'pending' entry\n\t *\n\t * @param request The request to enqueue\n\t * @param id Optional ID to use for the entry -- if not provided, a new\n\t * ID will be generated. If the ID is already in use then\n\t * nothing will be added.\n\t * @returns The ID for the newly created pending entry\n\t */\n\tadd: (request: KeetaAnchorQueueRequest<QueueRequest>, info?: KeetaAnchorQueueEntryExtra) => Promise<KeetaAnchorQueueRequestID>;\n\n\t/**\n\t * Update the status of an entry in the queue\n\t *\n\t * If the status is \"failed_temporarily\", the failure count will be incremented\n\t *\n\t * @param id The entry ID to update\n\t * @param status The new status of the entry\n\t * @param ancillary Optional ancillary data for the status update\n\t * @returns void\n\t */\n\tsetStatus: (id: KeetaAnchorQueueRequestID, status: KeetaAnchorQueueStatus, ancillary?: KeetaAnchorQueueEntryAncillaryData<QueueResult>) => Promise<void>;\n\n\t/**\n\t * Get entries from storage with an optional filter\n\t *\n\t * @param filter The filter to apply (optional)\n\t * @returns An array of entries matching the criteria\n\t */\n\tquery(filter?: KeetaAnchorQueueFilter): Promise<KeetaAnchorQueueEntry<QueueRequest, QueueResult>[]>;\n\n\t/**\n\t * Get a single entry from storage by ID\n\t *\n\t * @param id The ID of the entry to retrieve\n\t * @returns The entry if found, or null if not found\n\t */\n\tget(id: KeetaAnchorQueueRequestID): Promise<KeetaAnchorQueueEntry<QueueRequest, QueueResult> | null>;\n\n\t/**\n\t * Perform maintenance tasks on the storage driver\n\t * (e.g. cleaning up old entries, etc)\n\t *\n\t * @returns void\n\t */\n\tmaintain?: () => Promise<void>;\n\n\t/**\n\t * Create a partitioned view of the queue\n\t *\n\t * @param partitionID The partition ID to use\n\t * @returns A new storage driver instance for the partition\n\t */\n\tpartition: (path: string) => Promise<KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>>;\n\n\t/**\n\t * Close the storage driver and release any resources\n\t */\n\tdestroy(): Promise<void>;\n\t[Symbol.asyncDispose](): Promise<void>;\n\n\t/** @internal */\n\t_Testing?: (key: string) => {\n\t\tsetToctouDelay?(delay: number): void;\n\t\tunsetToctouDelay?(): void;\n\t};\n}\n\n/**\n * An in-memory implementation of the KeetaAnchorQueueStorageDriver\n */\nexport class KeetaAnchorQueueStorageDriverMemory<QueueRequest extends JSONSerializable = JSONSerializable, QueueResult extends JSONSerializable = JSONSerializable> implements KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult> {\n\tprotected queueStorage: { [path: string]: KeetaAnchorQueueEntry<QueueRequest, QueueResult>[]; } = {};\n\tprotected readonly logger?: Logger | undefined;\n\tprotected partitionCounter = 0;\n\tprivate destroyed = false;\n\treadonly name: string = 'KeetaAnchorQueueStorageDriverMemory';\n\treadonly id: string;\n\treadonly path: string[] = [];\n\n\tconstructor(options?: KeetaAnchorQueueStorageOptions) {\n\t\tthis.id = options?.id ?? crypto.randomUUID();\n\t\tthis.logger = options?.logger;\n\t\tthis.path.push(...(options?.path ?? []));\n\t\tObject.freeze(this.path);\n\n\t\tthis.methodLogger('new')?.debug('Created new in-memory queue storage driver');\n\t}\n\n\tprotected clone(options?: Partial<KeetaAnchorQueueStorageOptions>): KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult> {\n\t\tconst cloned = new KeetaAnchorQueueStorageDriverMemory<QueueRequest, QueueResult>({\n\t\t\tlogger: this.logger,\n\t\t\tid: `${this.id}::${this.partitionCounter++}`,\n\t\t\tpath: [...this.path],\n\t\t\t...options\n\t\t});\n\t\tcloned.queueStorage = this.queueStorage;\n\n\t\treturn(cloned);\n\t}\n\n\tprotected get queue(): KeetaAnchorQueueEntry<QueueRequest, QueueResult>[] {\n\t\tconst pathKey = ['root', ...this.path].join('.');\n\t\tlet retval = this.queueStorage[pathKey];\n\t\tif (retval === undefined) {\n\t\t\tretval = this.queueStorage[pathKey] = [];\n\t\t}\n\t\treturn(retval);\n\t}\n\n\tprotected methodLogger(method: string): Logger | undefined {\n\t\treturn(MethodLogger(this.logger, {\n\t\t\tclass: 'KeetaAnchorQueueStorageDriverMemory',\n\t\t\tfile: 'src/lib/queue/index.ts',\n\t\t\tmethod: method,\n\t\t\tinstanceID: this.id\n\t\t}));\n\t}\n\n\tprivate checkDestroyed(): void {\n\t\tif (this.destroyed) {\n\t\t\tthrow(new Error('Queue has been destroyed'));\n\t\t}\n\t}\n\n\tasync add(request: KeetaAnchorQueueRequest<QueueRequest>, info?: KeetaAnchorQueueEntryExtra): Promise<KeetaAnchorQueueRequestID> {\n\t\tthis.checkDestroyed();\n\n\t\tconst logger = this.methodLogger('add');\n\n\t\tlet id = ConvertStringToRequestID(info?.id);\n\t\tif (id) {\n\t\t\tconst duplicateID = this.queue.some(function(checkEntry) {\n\t\t\t\treturn(checkEntry.id === id);\n\t\t\t});\n\n\t\t\tif (duplicateID) {\n\t\t\t\tlogger?.debug(`Request with id ${String(id)} already exists, ignoring`);\n\n\t\t\t\treturn(id);\n\t\t\t}\n\t\t}\n\n\t\tconst idempotentIDs = info?.idempotentKeys;\n\t\tif (idempotentIDs) {\n\t\t\tconst matchingIdempotentEntries = new Set<KeetaAnchorQueueRequestID>();\n\t\t\tfor (const idempotentID of idempotentIDs) {\n\t\t\t\tconst idempotentEntryExists = this.queue.some(function(checkEntry) {\n\t\t\t\t\treturn(checkEntry.idempotentKeys?.has(idempotentID) ?? false);\n\t\t\t\t});\n\n\t\t\t\tif (idempotentEntryExists) {\n\t\t\t\t\tmatchingIdempotentEntries.add(idempotentID);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matchingIdempotentEntries.size !== 0) {\n\t\t\t\tthrow(new Errors.IdempotentExistsError('One or more idempotent entries already exist in the queue', matchingIdempotentEntries));\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * The status to use for the new entry\n\t\t */\n\t\tconst status = info?.status ?? 'pending';\n\n\t\t/*\n\t\t * The ID is a branded string, so we must convert the generated UUID\n\t\t */\n\t\tid ??= ConvertStringToRequestID(crypto.randomUUID());\n\n\t\tlogger?.debug(`Enqueuing request with id ${String(id)}`);\n\n\t\tthis.queue.push({\n\t\t\tid: id,\n\t\t\trequest: request,\n\t\t\toutput: null,\n\t\t\tlastError: null,\n\t\t\tstatus: status,\n\t\t\tfailures: 0,\n\t\t\tcreated: new Date(),\n\t\t\tupdated: new Date(),\n\t\t\tworker: null,\n\t\t\tidempotentKeys: idempotentIDs ? new Set(idempotentIDs) : undefined\n\t\t});\n\n\t\treturn(id);\n\t}\n\n\tasync setStatus(id: KeetaAnchorQueueRequestID, status: KeetaAnchorQueueStatus, ancillary?: KeetaAnchorQueueEntryAncillaryData<QueueResult>): Promise<void> {\n\t\tthis.checkDestroyed();\n\n\t\tconst logger = this.methodLogger('setStatus');\n\n\t\tconst entry = this.queue.find(function(checkEntry) {\n\t\t\treturn(checkEntry.id === id);\n\t\t});\n\t\tif (!entry) {\n\t\t\tthrow(new Error(`Request with ID ${String(id)} not found`));\n\t\t}\n\n\t\tconst changedFields = ManageStatusUpdates<QueueResult>(id, entry, status, ancillary, logger);\n\n\t\tObject.assign(entry, changedFields);\n\t}\n\n\tasync get(id: KeetaAnchorQueueRequestID): Promise<KeetaAnchorQueueEntry<QueueRequest, QueueResult> | null> {\n\t\tthis.checkDestroyed();\n\n\t\tconst entry = this.queue.find(function(checkEntry) {\n\t\t\treturn(checkEntry.id === id);\n\t\t});\n\n\t\tif (!entry) {\n\t\t\treturn(null);\n\t\t}\n\n\t\treturn(structuredClone(entry));\n\t}\n\n\tasync query(filter?: KeetaAnchorQueueFilter): Promise<KeetaAnchorQueueEntry<QueueRequest, QueueResult>[]> {\n\t\tthis.checkDestroyed();\n\n\t\tconst logger = this.methodLogger('query');\n\n\t\tconst queueDuplicate = structuredClone(this.queue);\n\n\t\tlogger?.debug(`Querying queue with id ${this.id} with filter:`, filter);\n\n\t\tconst allEntriesInStatus = (function() {\n\t\t\tconst filterStatus = filter?.status;\n\t\t\tconst filterLastUpdateBefore = filter?.updatedBefore;\n\t\t\tif (filterStatus || filterLastUpdateBefore) {\n\t\t\t\treturn(queueDuplicate.filter(function(entry) {\n\t\t\t\t\tif (filterStatus) {\n\t\t\t\t\t\tif (entry.status !== filterStatus) {\n\t\t\t\t\t\t\treturn(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (filterLastUpdateBefore) {\n\t\t\t\t\t\tif (entry.updated >= filterLastUpdateBefore) {\n\t\t\t\t\t\t\treturn(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn(true);\n\t\t\t\t}));\n\t\t\t} else {\n\t\t\t\treturn(queueDuplicate);\n\t\t\t}\n\t\t})();\n\n\t\tlet retval = allEntriesInStatus;\n\t\tif (filter?.limit !== undefined) {\n\t\t\tretval = allEntriesInStatus.slice(0, filter.limit);\n\t\t}\n\n\t\tlogger?.debug(`Queried queue with id ${this.id} with filter:`, filter, '-- found', retval.length, 'entries');\n\n\t\treturn(retval);\n\t}\n\n\tasync partition(path: string): Promise<KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>> {\n\t\tthis.checkDestroyed();\n\n\t\tconst logger = this.methodLogger('partition');\n\n\t\tlogger?.debug(`Creating partitioned queue storage driver for path \"${path}\"`);\n\n\t\tconst partitioned = this.clone({\n\t\t\tpath: [...this.path, path]\n\t\t});\n\n\t\treturn(partitioned);\n\t}\n\n\tasync destroy(): Promise<void> {\n\t\tthis.destroyed = true;\n\t\tthis.methodLogger('destroy')?.debug('Destroying in-memory queue');\n\t}\n\n\tasync [Symbol.asyncDispose](): Promise<void> {\n\t\treturn(await this.destroy());\n\t}\n}\n\ninterface AdditionalPipeOptions {\n\t/**\n\t * If true, call maintain/run on this target when maintaining/running this runner\n\t * Defaults to true\n\t */\n\texclusiveTarget?: boolean;\n}\n\n// @ts-ignore\nexport interface KeetaAnchorQueueRunnerConfigurationObject {\n\tmaxRetries: number;\n\tprocessTimeout: number;\n\tbatchSize: number;\n\tretryDelay: number;\n\tstuckMultiplier: number;\n}\n\n// Ensure that KeetaAnchorQueueRunnerConfigurationObject has all the required properties of KeetaAnchorQueueRunner, and no extra properties\n// if this assertion fails, it means that KeetaAnchorQueueRunnerConfigurationObject is missing a property from KeetaAnchorQueueRunner or has an extra property\n// @ts-ignore\ntype __check_KeetaAnchorQueueRunnerConfigurationObject = Required<Pick<KeetaAnchorQueueRunner, 'maxRetries' | 'retryDelay' | 'stuckMultiplier' | 'batchSize' | 'processTimeout'>>;\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype __check = AssertNever<__check_KeetaAnchorQueueRunnerConfigurationObject extends KeetaAnchorQueueRunnerConfigurationObject ? (KeetaAnchorQueueRunnerConfigurationObject extends __check_KeetaAnchorQueueRunnerConfigurationObject ? never : false) : false>;\n\n/**\n * A Queue Runner and Request Translator for processing entries in a queue\n *\n * The queue runner is responsible for pulling entries from the queue,\n * processing them, and updating their status in the queue. As well\n * as moving jobs between queues by piping the output of one runner\n * to another. Additionally, maintenance tasks such as re-queuing\n * failed jobs and marking stuck jobs are also handled by the runner.\n *\n * This is an abstract base class that must be extended to provide\n * the actual processing logic as well as the encoding and decoding\n * for requests and responses.\n */\nexport abstract class KeetaAnchorQueueRunner<UserRequest = unknown, UserResult = unknown, QueueRequest extends JSONSerializable = JSONSerializable, QueueResult extends JSONSerializable = JSONSerializable> {\n\t/**\n\t * The queue this runner is responsible for running\n\t */\n\tprivate readonly queue: KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>;\n\t/**\n\t * The logger we should use for logging anything\n\t */\n\tprivate readonly logger?: Logger | undefined;\n\t/**\n\t * The processor function to use for processing entries\n\t */\n\tprotected abstract processor(entry: KeetaAnchorQueueEntry<UserRequest, UserResult>): Promise<{ status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; }>;\n\n\t/**\n\t * The processor for stuck jobs (optional)\n\t */\n\tprotected processorStuck?(entry: KeetaAnchorQueueEntry<UserRequest, UserResult>): Promise<{ status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; }>;\n\n\t/**\n\t * The processor for aborted jobs (optional)\n\t */\n\tprotected processorAborted?(entry: KeetaAnchorQueueEntry<UserRequest, UserResult>): Promise<{ status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; }>;\n\n\t/**\n\t * Worker configuration\n\t */\n\tprivate readonly workers: NonNullable<KeetaAnchorQueueRunnerOptions['workers']>;\n\tprivate readonly workerID: KeetaAnchorQueueWorkerID;\n\n\t/**\n\t * Pipes to other runners we have registered\n\t */\n\tprivate readonly pipes: (\n\t\t// Non-Batch pipe -- depending on acceptStatus, either UserResult[] or UserRequest[]\n\t\t(\n\t\t\t({\n\t\t\t\tisBatchPipe: false;\n\t\t\t} & ({\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\ttarget: KeetaAnchorQueueRunner<UserResult, any, QueueResult, any>\n\t\t\t\tacceptStatus: Extract<KeetaAnchorPipeableQueueStatus, 'completed'>;\n\t\t\t} | {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\ttarget: KeetaAnchorQueueRunner<UserRequest, any, QueueResult, any>\n\t\t\t\tacceptStatus: Extract<KeetaAnchorPipeableQueueStatus, 'failed_permanently'>;\n\t\t\t})) |\n\n\t\t\t// Batch pipe -- depending on acceptStatus, either UserResult[] or UserRequest[]\n\t\t\t({\n\t\t\t\tisBatchPipe: true;\n\t\t\t\tminBatchSize: number;\n\t\t\t\tmaxBatchSize: number;\n\t\t\t} & ({\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\ttarget: KeetaAnchorQueueRunner<UserResult[], any, JSONSerializable, any>;\n\t\t\t\tacceptStatus: Extract<KeetaAnchorPipeableQueueStatus, 'completed'>;\n\t\t\t} | {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\ttarget: KeetaAnchorQueueRunner<UserRequest[], any, JSONSerializable, any>;\n\t\t\t\tacceptStatus: Extract<KeetaAnchorPipeableQueueStatus, 'failed_permanently'>;\n\t\t\t}))\n\t\t) & AdditionalPipeOptions\n\t)[] = [];\n\n\t/**\n\t * Initialization promise\n\t */\n\tprivate initializePromise: Promise<void> | undefined;\n\n\t/**\n\t * Configuration for this queue\n\t */\n\t/**\n\t * The maximum number of times to retry a failed job before giving up\n\t * and marking it as permanently failed\n\t */\n\tprotected maxRetries = 5;\n\t/**\n\t * The amount of time to allow a job to run before considering it\n\t * timed out and marking it as aborted, the `aborted` processor\n\t * (if provided) will be responsible for determining what to do with\n\t * the job at that point (e.g. retry it, mark it as failed, etc)\n\t * because some work from the job may have been completed\n\t * before the timeout was reached -- it could even still be on-going\n\t * after the timeout is reached, so the `aborted` processor should be\n\t * prepared to handle that situation as well.\n\t */\n\tprotected processTimeout = 300_000; /* 5 minutes */\n\t/**\n\t * When piping a batch of jobs to another runner, this is the number\n\t * of jobs to include in each batch (max).\n\t */\n\tprotected batchSize = 100;\n\n\t/**\n\t * The amount of time to wait before retrying a failed job -- this should\n\t * be long enough to allow any transient issues to be resolved (e.g. a downstream\n\t * service to come back up, etc) but not so long that it causes excessive\n\t * delays in processing.\n\t *\n\t * Keep in mind that after the {@link maxRetries} is reached, the job will\n\t * be marked as permanently failed, so if the retry delay is too low then\n\t * it could cause jobs to be marked as permanently failed before transient\n\t * issues have a chance to be resolved.\n\t */\n\tprotected get retryDelay(): number {\n\t\tif (this.internalRetryDelay !== undefined) {\n\t\t\treturn(this.internalRetryDelay);\n\t\t}\n\t\treturn(this.processTimeout * 10);\n\t}\n\n\tprotected set retryDelay(value: number) {\n\t\tthis.internalRetryDelay = value;\n\t}\n\n\tprivate internalRetryDelay?: number;\n\n\t/**\n\t * The number of {@link processTimeout} intervals to wait before\n\t * considering a job to be stuck -- this is for jobs that are\n\t * still in the 'processing' state but have not updated their\n\t * timestamp in a long time, which likely indicates that the worker\n\t * processing the job has died or is otherwise no longer making\n\t * progress on the job.\n\t *\n\t * Like the `aborted` status, the `stuck` status means the job is in\n\t * an indeterminate state where it may have done some of the work of\n\t * the processor but we don't know how much (if any) of it was\n\t * completed, so the `stuck` processor should be prepared to handle\n\t * that situation. It is unlikely that the job is still being actively\n\t * processed by a worker at this point, but it is possible, so the\n\t * `stuck` processor should be prepared to handle that as well.\n\t */\n\tprotected get stuckMultiplier(): number {\n\t\tif (this.internalStuckMultiplier !== undefined) {\n\t\t\treturn(this.internalStuckMultiplier);\n\t\t}\n\t\treturn(10);\n\t}\n\n\tprotected set stuckMultiplier(value: number) {\n\t\tthis.internalStuckMultiplier = value;\n\t}\n\n\tprivate internalStuckMultiplier?: number;\n\n\t/**\n\t * How many runners can process this queue in parallel\n\t */\n\tprotected maxRunners?: number;\n\tprivate readonly runnerLockKey: KeetaAnchorQueueRequestID;\n\n\t/**\n\t * The ID of this runner for diagnostic purposes\n\t */\n\treadonly id: string;\n\n\tconstructor(config: { queue: KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>; } & KeetaAnchorQueueRunnerOptions) {\n\t\tthis.queue = config.queue;\n\t\tthis.logger = config.logger;\n\t\tthis.workers = config.workers ?? {\n\t\t\tcount: 1,\n\t\t\tid: 0\n\t\t};\n\n\t\tif (this.workers.id < 0) {\n\t\t\tthrow(new Error('Worker ID cannot be negative'));\n\t\t}\n\n\t\tif (this.maxRunners) {\n\t\t\tif (this.workers.id > this.maxRunners - 1 || this.workers.count > this.maxRunners) {\n\t\t\t\tthrow(new Error('Worker ID other than 0 or worker count other than 1 is not supported yet'));\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * The worker ID is just a branded version of the worker number\n\t\t */\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\tthis.workerID = this.workers.id as KeetaAnchorQueueWorkerID;\n\n\t\t/*\n\t\t * The runner lock key, a unique key used to ensure only\n\t\t * one instance of a given runner is running at a time\n\t\t */\n\t\tthis.runnerLockKey = ConvertStringToRequestID(`@runner-lock:9ba756f0-7aa2-41c7-a1ea-b010dc752ae8.worker.${this.workerID}`);\n\n\t\t/**\n\t\t * Instance ID\n\t\t */\n\t\tthis.id = config.id ?? crypto.randomUUID();\n\n\t\tthis.methodLogger('new')?.debug('Created new queue runner attached to queue', this.queue.id);\n\t}\n\n\tprivate async initialize(): Promise<void> {\n\t\tif (this.initializePromise) {\n\t\t\treturn(await this.initializePromise);\n\t\t}\n\n\t\t/* Ensure the sequential lock entry exists */\n\t\tthis.initializePromise = (async () => {\n\t\t\t/*\n\t\t\t * We store `null` as the request value because we\n\t\t\t * don't have anything better to store -- it's not\n\t\t\t * always going to be compatible with the type\n\t\t\t * QueueRequest but we know that we will never actually\n\t\t\t * use the value.\n\t\t\t */\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tawait this.queue.add(null as unknown as QueueRequest, {\n\t\t\t\tid: this.runnerLockKey,\n\t\t\t\tstatus: '@internal'\n\t\t\t});\n\t\t})();\n\n\t\treturn(await this.initializePromise);\n\t}\n\n\tprotected setConfiguration(parameters: Partial<KeetaAnchorQueueRunnerConfigurationObject>): void {\n\t\tconst parameterNames = [ 'batchSize', 'maxRetries', 'processTimeout', 'retryDelay', 'stuckMultiplier' ] as const satisfies (keyof typeof parameters)[];\n\t\t// Ensure that all keys in the config object are expected and used\n\t\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t\ttype __checkAllExtensionConfigKeysAreValid = AssertNever<Exclude<keyof typeof parameters, typeof parameterNames[number]>>;\n\n\t\tfor (const parameterName of parameterNames) {\n\t\t\tconst value = parameters[parameterName];\n\t\t\tif (value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis[parameterName] = value;\n\t\t}\n\t}\n\n\tprivate methodLogger(method: string): Logger | undefined {\n\t\treturn(MethodLogger(this.logger, {\n\t\t\tclass: 'KeetaAnchorQueueRunner',\n\t\t\tfile: 'src/lib/queue/index.ts',\n\t\t\tmethod: method,\n\t\t\tinstanceID: this.id\n\t\t}));\n\t}\n\n\t/** @internal */\n\t_Testing(key: string): {\n\t\tsetParams: (params: Partial<KeetaAnchorQueueRunnerConfigurationObject> & { maxRunners?: number; }) => void;\n\t\tqueue: () => KeetaAnchorQueueStorageDriver<QueueRequest, QueueResult>;\n\t\tmarkWorkerAsProcessing: () => Promise<void>;\n\t} {\n\t\tif (key !== 'bc81abf8-e43b-490b-b486-744fb49a5082') {\n\t\t\tthrow(new Error('This is a testing only method'));\n\t\t}\n\n\t\treturn({\n\t\t\tsetParams: (params: Partial<KeetaAnchorQueueRunnerConfigurationObject> & { maxRunners?: number; }) => {\n\t\t\t\tconst { maxRunners, ...configParams } = params;\n\t\t\t\tthis.setConfiguration(configParams);\n\n\t\t\t\tif (maxRunners !== undefined) {\n\t\t\t\t\tthis.maxRunners = maxRunners;\n\t\t\t\t}\n\t\t\t},\n\t\t\tqueue: () => {\n\t\t\t\treturn(this.queue);\n\t\t\t},\n\t\t\tmarkWorkerAsProcessing: async () => {\n\t\t\t\tawait this.queue.setStatus(this.runnerLockKey, 'processing', {\n\t\t\t\t\toldStatus: '@internal',\n\t\t\t\t\tby: this.workerID\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected abstract decodeRequest(request: QueueRequest): UserRequest;\n\tprotected abstract decodeResponse(response: QueueResult | null): UserResult | null;\n\n\tprotected abstract encodeRequest(request: UserRequest): QueueRequest;\n\tprotected abstract encodeResponse(response: UserResult | null): QueueResult | null;\n\n\tprotected decodeEntry(entry: KeetaAnchorQueueEntry<QueueRequest, QueueResult>): KeetaAnchorQueueEntry<UserRequest, UserResult> {\n\t\treturn({\n\t\t\t...entry,\n\t\t\trequest: this.decodeRequest(entry.request),\n\t\t\toutput: this.decodeResponse(entry.output)\n\t\t});\n\t}\n\n\t/**\n\t * Enqueue an item to be processed by the queue\n\t */\n\tasync add(request: UserRequest, info?: KeetaAnchorQueueEntryExtra): Promise<KeetaAnchorQueueRequestID> {\n\t\tawait this.initialize();\n\n\t\tconst encodedRequest = this.encodeRequest(request);\n\t\tconst newID = await this.queue.add(encodedRequest, info);\n\t\treturn(newID);\n\t}\n\n\t/**\n\t * Get a single entry from storage by ID\n\t */\n\tasync get(id: KeetaAnchorQueueRequestID): Promise<KeetaAnchorQueueEntry<UserRequest, UserResult> | null> {\n\t\tawait this.initialize();\n\n\t\tconst entry = await this.queue.get(id);\n\t\tif (!entry) {\n\t\t\treturn(null);\n\t\t}\n\n\t\treturn(this.decodeEntry(entry));\n\t}\n\n\t/**\n\t * Get entries from storage with an optional filter\n\t */\n\tasync query(filter?: KeetaAnchorQueueFilter): Promise<KeetaAnchorQueueEntry<UserRequest, UserResult>[]> {\n\t\tawait this.initialize();\n\n\t\tconst entries = await this.queue.query(filter);\n\t\treturn(entries.map((entry) => {\n\t\t\treturn(this.decodeEntry(entry));\n\t\t}));\n\t}\n\n\t/**\n\t * Set the status of an entry in the queue\n\t */\n\tasync setStatus(id: KeetaAnchorQueueRequestID, status: KeetaAnchorQueueStatus, ancillary?: KeetaAnchorQueueEntryAncillaryData<UserResult>): Promise<void> {\n\t\tawait this.initialize();\n\n\t\tlet encodedOutput: QueueResult | null | undefined = undefined;\n\t\tif (ancillary?.output !== undefined) {\n\t\t\tencodedOutput = this.encodeResponse(ancillary.output);\n\t\t}\n\n\t\treturn(await this.queue.setStatus(id, status, {\n\t\t\t...ancillary,\n\t\t\toutput: encodedOutput\n\t\t}));\n\t}\n\n\t/**\n\t * Checks to see if the queue is runnable\n\t */\n\tasync runnable(): Promise<boolean> {\n\t\tawait this.initialize();\n\n\t\tconst pendingEntries = await this.queue.query({ status: 'pending', limit: 1 });\n\t\tif (pendingEntries.length > 0) {\n\t\t\treturn(true);\n\t\t}\n\n\t\tfor (const pipe of this.pipes) {\n\t\t\tconst pipeRunnable = await pipe.target.runnable();\n\t\t\tif (pipeRunnable) {\n\t\t\t\treturn(true);\n\t\t\t}\n\t\t}\n\n\t\treturn(false);\n\t}\n\n\tprivate async updateRunnerLockTimestamp(): Promise<void> {\n\t\tconst logger = this.methodLogger('updateRunnerLockTimestamp');\n\n\t\ttry {\n\t\t\tlogger?.debug('Updating sequential processing lock timestamp for worker ID', this.workerID);\n\t\t\tawait this.queue.setStatus(this.runnerLockKey, 'processing', {\n\t\t\t\toldStatus: 'processing',\n\t\t\t\tby: this.workerID\n\t\t\t});\n\t\t\tlogger?.debug('Updated sequential processing lock timestamp for worker ID', this.workerID);\n\t\t} catch (error: unknown) {\n\t\t\tlogger?.error('Failed to update sequential processing lock timestamp for worker ID', this.workerID, ':', error);\n\t\t\tthrow(error);\n\t\t}\n\t}\n\n\tprivate async getRunnerLock(cleanup: InstanceType<typeof AsyncDisposableStack>): Promise<boolean> {\n\t\tconst logger = this.methodLogger('getRunnerLock');\n\n\t\ttry {\n\t\t\tlogger?.debug('Acquiring sequential processing lock for worker ID', this.workerID);\n\t\t\tawait this.queue.setStatus(this.runnerLockKey, 'processing', {\n\t\t\t\toldStatus: '@internal',\n\t\t\t\tby: this.workerID\n\t\t\t});\n\t\t\tlogger?.debug('Acquired sequential processing lock for worker ID', this.workerID);\n\t\t} catch (error: unknown) {\n\t\t\tif (Errors.IncorrectStateAssertedError.isInstance(error)) {\n\t\t\t\treturn(false);\n\t\t\t}\n\n\t\t\tthrow(error);\n\t\t}\n\n\t\tcleanup.defer(async () => {\n\t\t\tfor (let retry = 0; retry < 10; retry++) {\n\t\t\t\tlogger?.debug(`Releasing sequential processing lock try #${retry + 1} for worker ID`, this.workerID);\n\t\t\t\ttry {\n\t\t\t\t\tawait this.queue.setStatus(this.runnerLockKey, '@internal', {\n\t\t\t\t\t\toldStatus: 'processing',\n\t\t\t\t\t\tby: undefined\n\t\t\t\t\t});\n\t\t\t\t} catch {\n\t\t\t\t\tawait asleep(1000);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\treturn(true);\n\t}\n\n\tprivate async maintainRunnerLock(): Promise<void> {\n\t\tconst logger = this.methodLogger('maintainRunnerLock');\n\t\tconst moment = new Date();\n\t\tawait using cleanup = new AsyncDisposableStack();\n\n\t\tconst obtained = await this.getRunnerLock(cleanup);\n\t\tif (obtained) {\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Check to see if the lock is stale\n\t\t */\n\t\tconst lockEntry = await this.queue.get(this.runnerLockKey);\n\n\t\tif (!lockEntry) {\n\t\t\treturn;\n\t\t}\n\t\tconst lockAge = moment.getTime() - lockEntry.updated.getTime();\n\t\tif (lockAge > this.processTimeout * this.stuckMultiplier) {\n\t\t\tlogger?.warn('Processing lock is stale, taking over lock for worker ID', this.workerID);\n\n\t\t\tawait this.queue.setStatus(this.runnerLockKey, '@internal', {\n\t\t\t\toldStatus: 'processing',\n\t\t\t\tby: this.workerID\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Run the queue processor\n\t *\n\t * Processes up to `batchSize` entries from the queue and returns\n\t * true if there may be more work to do, or false if the queue\n\t * is empty.\n\t *\n\t * @param options Optional run options\n\t */\n\tasync run(options?: KeetaAnchorQueueRunOptions): Promise<boolean> {\n\t\tconst timeout = options?.timeoutMs;\n\n\t\tawait this.initialize();\n\n\t\tconst logger = this.methodLogger('run');\n\t\tconst batchSize = this.batchSize;\n\t\tconst processTimeout = this.processTimeout;\n\t\tawait using cleanup = new AsyncDisposableStack();\n\n\t\tlet retval = true;\n\n\t\tconst startTime = Date.now();\n\n\t\tconst locked = await this.getRunnerLock(cleanup);\n\t\tif (!locked) {\n\t\t\tlogger?.debug('Another worker is already processing the queue, skipping run');\n\n\t\t\treturn(true);\n\t\t}\n\n\t\tconst processJobOk = Symbol('processJobOk');\n\t\tconst processJobTimeout = Symbol('processJobTimeout');\n\n\t\tconst processJob = async (index: number, entry: KeetaAnchorQueueEntry<QueueRequest, QueueResult>, startingStatus: KeetaAnchorQueueStatus, processor: (entry: KeetaAnchorQueueEntry<UserRequest, UserResult>) => Promise<{ status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; }>): Promise<typeof processJobTimeout | typeof processJobOk> => {\n\t\t\tif (timeout !== undefined) {\n\t\t\t\tconst elapsed = Date.now() - startTime;\n\t\t\t\tif (elapsed >= timeout) {\n\t\t\t\t\tlogger?.debug(`Timeout of ${timeout}ms reached after processing ${index} entries (${startingStatus} phase; elapsed ${elapsed}ms)`);\n\n\t\t\t\t\treturn(processJobTimeout);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait this.updateRunnerLockTimestamp();\n\n\t\t\tlet setEntryStatus: { status: KeetaAnchorQueueStatus; output: UserResult | null; error?: string | undefined; } = { status: 'failed_temporarily', output: null };\n\n\t\t\tlogger?.debug(`Processing entry request with id ${String(entry.id)}`);\n\n\t\t\ttry {\n\t\t\t\t/*\n\t\t\t\t * Get a lock by setting it to 'processing'\n\t\t\t\t */\n\t\t\t\tawait this.queue.setStatus(entry.id, 'processing', { oldStatus: startingStatus, by: this.workerID });\n\n\t\t\t\t/*\n\t\t\t\t * Process the entry with a timeout, if the timeout is reached\n\t\t\t\t * we should mark the process as aborted because we no longer\n\t\t\t\t * know what state the work is in and someone will need to\n\t\t\t\t * inspect the job and determine through some other means if\n\t\t\t\t * it is completed or failed.\n\t\t\t\t */\n\t\t\t\tlet timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n\t\t\t\tsetEntryStatus = await Promise.race([\n\t\t\t\t\tnew Promise<{ status: 'aborted', output: null }>(function(resolve) {\n\t\t\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\t\t\tresolve({ status: 'aborted', output: null });\n\t\t\t\t\t\t}, processTimeout);\n\t\t\t\t\t}),\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn(await processor(this.decodeEntry(entry)));\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tif (timeoutTimer) {\n\t\t\t\t\t\t\t\tclearTimeout(timeoutTimer);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})()\n\t\t\t\t]);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tif (Errors.IncorrectStateAssertedError.isInstance(error)) {\n\t\t\t\t\tlogger?.info(`Skipping request with id ${String(entry.id)} because it is no longer in the expected state \"${startingStatus}\"`, error);\n\n\t\t\t\t\treturn(processJobOk);\n\t\t\t\t}\n\n\t\t\t\tlogger?.error(`Failed to process request with id ${String(entry.id)}, setting state to \"${setEntryStatus.status}\":`, error);\n\t\t\t\tsetEntryStatus.status = 'failed_temporarily';\n\t\t\t\tsetEntryStatus.error = String(error);\n\t\t\t}\n\n\t\t\tif (setEntryStatus.status === 'processing') {\n\t\t\t\tlogger?.error(`Processor for request with id ${String(entry.id)} returned invalid status \"processing\"`);\n\t\t\t\tsetEntryStatus.status = 'failed_temporarily';\n\t\t\t\tsetEntryStatus.error = 'Processor returned invalid status \"processing\"';\n\t\t\t}\n\n\t\t\tlet by: KeetaAnchorQueueWorkerID | undefined = this.workerID;\n\t\t\tif (setEntryStatus.status === 'pending') {\n\t\t\t\tby = undefined;\n\t\t\t}\n\n\t\t\tawait this.queue.setStatus(entry.id, setEntryStatus.status, { oldStatus: 'processing', by: by, output: this.encodeResponse(setEntryStatus.output), error: setEntryStatus.error });\n\n\t\t\treturn(processJobOk);\n\t\t};\n\n\t\t/*\n\t\t * Process pending jobs first\n\t\t */\n\t\tfor (let index = 0; index < batchSize; index++) {\n\t\t\tconst entries = await this.queue.query({ status: 'pending', limit: 1 });\n\t\t\tconst entry = entries[0];\n\t\t\tif (entry === undefined) {\n\t\t\t\tretval = false;\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst result = await processJob(index, entry, 'pending', this.processor.bind(this));\n\t\t\tif (result === processJobTimeout) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * Next process any pipes to other runners\n\t\t */\n\t\tconst pipes = [...this.pipes];\n\t\tfor (const pipe of pipes) {\n\t\t\tif (pipe.exclusiveTarget === false) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet remainingTime: number | undefined = undefined;\n\t\t\tif (timeout !== undefined) {\n\t\t\t\tconst elapsed = Date.now() - startTime;\n\t\t\t\tremainingTime = timeout - elapsed;\n\t\t\t\tif (remainingTime <= 0) {\n\t\t\t\t\tremainingTime = -1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pipeHasMoreWork = await pipe.target.run({\n\t\t\t\t...options,\n\t\t\t\ttimeoutMs: remainingTime\n\t\t\t});\n\n\t\t\tif (pipeHasMoreWork) {\n\t\t\t\tretval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Process stuck or aborted jobs (if possible)\n\t\t */\n\t\tconst conditions = [{\n\t\t\tstatus: 'aborted' as const,\n\t\t\tprocessor: this.processorAborted?.bind(this)\n\t\t}, {\n\t\t\tstatus: 'stuck' as const,\n\t\t\tprocessor: this.processorStuck?.bind(this)\n\t\t}];\n\n\t\tlet timeoutReached = false;\n\t\tfor (const condition of conditions) {\n\t\t\tif (condition.processor === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (let index = 0; index < batchSize; index++) {\n\t\t\t\tconst entries = await this.queue.query({ status: condition.status, limit: 1 });\n\t\t\t\tconst entry = entries[0];\n\t\t\t\tif (entry === undefined) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst result = await processJob(index, entry, condition.status, condition.processor);\n\t\t\t\tif (result === processJobTimeout) {\n\t\t\t\t\ttimeoutReached = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (timeoutReached) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn(retval);\n\t}\n\n\tprivate async markStuckRequestsAsStuck(): Promise<void> {\n\t\tconst stuckThreshold = this.processTimeout * this.stuckMultiplier;\n\n\t\tconst logger = this.methodLogger('markStuckRequestsAsStuck');\n\t\tconst now = Date.now();\n\n\t\tconst requests = await this.queue.query({ status: 'processing', limit: 100, updatedBefore: new Date(now - stuckThreshold) });\n\t\tfor (const request of requests) {\n\t\t\t/*\n\t\t\t * Skip the runner lock entries, they are managed separately\n\t\t\t */\n\t\t\tif (request.id.toString().startsWith('@runner-lock:9ba756f0-7aa2-41c7-a1ea-b010dc752ae8.worker.')) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tlogger?.warn(`Marking request with id ${String(request.id)} as stuck`);\n\n\t\t\t\tawait this.queue.setStatus(request.id, 'stuck', { oldStatus: 'processing', by: this.workerID });\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.error(`Failed to mark request with id ${String(request.id)} as stuck:`, error);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async requeueFailedRequests(): Promise<void> {\n\t\tconst retryDelay = this.retryDelay;\n\t\tconst maxRetries = this.maxRetries;\n\n\t\tconst logger = this.methodLogger('requeueFailedRequests');\n\t\tconst now = Date.now();\n\n\t\tconst requests = await this.queue.query({ status: 'failed_temporarily', limit: 100, updatedBefore: new Date(now - retryDelay) });\n\t\tfor (const request of requests) {\n\t\t\ttry {\n\t\t\t\tif (request.failures >= maxRetries) {\n\t\t\t\t\tlogger?.info(`Request with id ${String(request.id)} has exceeded maximum retries, not requeuing -- moving to failed_permanently`);\n\t\t\t\t\tawait this.queue.setStatus(request.id, 'failed_permanently', { oldStatus: 'failed_temporarily', by: this.workerID });\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tlogger?.debug(`Requeuing failed request with id ${String(request.id)}`);\n\n\t\t\t\tawait this.queue.setStatus(request.id, 'pending', { oldStatus: 'failed_temporarily', by: this.workerID });\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.error(`Failed to requeue request with id ${String(request.id)}:`, error);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async moveCompletedToNextStage(statusTarget: KeetaAnchorPipeableQueueStatus): Promise<void> {\n\t\tconst logger = this.methodLogger('moveCompletedToNextStage');\n\n\t\tconst pipes = [...this.pipes].filter(function(pipe) {\n\t\t\treturn(pipe.acceptStatus === statusTarget);\n\t\t});\n\n\t\tif (pipes.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst allRequests = await this.queue.query({ status: statusTarget, limit: 100 });\n\t\tlet requests = allRequests;\n\n\t\tconst RequestSentToPipes = new Map<KeetaAnchorQueueRequestID, number>();\n\t\tfunction IncrRequestSentToPipes(requestID: KeetaAnchorQueueRequestID): void {\n\t\t\tconst sentCount = RequestSentToPipes.get(requestID) ?? 0;\n\t\t\tRequestSentToPipes.set(requestID, sentCount + 1);\n\t\t}\n\n\t\tconst getNextPipeRequestInput = (entry: KeetaAnchorQueueEntry<QueueRequest, QueueResult>) => {\n\t\t\tif (statusTarget === 'completed') {\n\t\t\t\treturn(this.decodeResponse(entry.output));\n\t\t\t} else if (statusTarget === 'failed_permanently') {\n\t\t\t\treturn(this.decodeRequest(entry.request));\n\t\t\t}\n\n\t\t\tassertNever(statusTarget);\n\t\t};\n\n\t\tfor (const pipe of pipes) {\n\t\t\tlogger?.debug('Processing pipe to target', pipe.target.id, pipe.isBatchPipe ? '(batch pipe)' : '(single item pipe)');\n\n\t\t\tif (pipe.isBatchPipe) {\n\t\t\t\t/**\n\t\t\t\t * Keep track of all the requests we successfully\n\t\t\t\t * sent to the target stage\n\t\t\t\t */\n\t\t\t\tconst allTargetSeenRequestIDs = new Set<KeetaAnchorQueueRequestID>();\n\n\t\t\t\t/**\n\t\t\t\t * During each iteration of the batch processing, we keep track\n\t\t\t\t * of the IDs we have already seen by the target and processed\n\t\t\t\t * so we don't try to reprocess them again\n\t\t\t\t */\n\t\t\t\tconst iterationTargetSeenRequestIDs = new Set<KeetaAnchorQueueRequestID>();\n\n\t\t\t\t/**\n\t\t\t\t * If we get a batch that cannot be added to the target pipe,\n\t\t\t\t * we just skip over them for retrying at a later date\n\t\t\t\t */\n\t\t\t\tconst skipRequestIDs = new Set<KeetaAnchorQueueRequestID>();\n\n\t\t\t\t/**\n\t\t\t\t * Compute a durable ID for this batch and target\n\t\t\t\t */\n\t\t\t\tlet batchID = ConvertStringToRequestID(crypto.randomUUID());\n\n\t\t\t\t/**\n\t\t\t\t * Keep track of sequential failures to find enough entries\n\t\t\t\t * and stop processing if we can't find enough after a few tries\n\t\t\t\t * in a row\n\t\t\t\t */\n\t\t\t\tlet sequentialFailureCount = 0;\n\n\t\t\t\tfor (;requests.length >= pipe.minBatchSize;\n\t\t\t\t\t/*\n\t\t\t\t\t * Remove any entries we have already seen during\n\t\t\t\t\t * the last iteration of the loop\n\t\t\t\t\t */\n\t\t\t\t\trequests = requests.filter(function(entry) {\n\t\t\t\t\t\treturn(!iterationTargetSeenRequestIDs.has(entry.id) && !skipRequestIDs.has(entry.id));\n\t\t\t\t\t})\n\t\t\t\t) {\n\t\t\t\t\titerationTargetSeenRequestIDs.clear();\n\n\t\t\t\t\tlogger?.debug(`Preparing to move ${statusTarget} requests to next stage ${pipe.target.id} (min=${pipe.minBatchSize}, max=${pipe.maxBatchSize}), have ${requests.length} ${statusTarget} requests available`);\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Compute a batch of entries to send to the next stage,\n\t\t\t\t\t * constrained to the max batch size of the pipe and\n\t\t\t\t\t * the entries which have non-null outputs\n\t\t\t\t\t */\n\t\t\t\t\tconst batchRaw = requests.map((entry) => {\n\t\t\t\t\t\treturn({ output: getNextPipeRequestInput(entry), id: entry.id });\n\t\t\t\t\t}).filter(function(entry): entry is { output: UserRequest | UserResult; id: KeetaAnchorQueueRequestID; } {\n\t\t\t\t\t\tif (entry === null) {\n\t\t\t\t\t\t\treturn(false);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn(true);\n\t\t\t\t\t}).slice(0, pipe.maxBatchSize);\n\n\t\t\t\t\t/*\n\t\t\t\t\t * If we don't have enough entries to meet the minimum\n\t\t\t\t\t * batch size, skip this iteration\n\t\t\t\t\t */\n\t\t\t\t\tif (batchRaw.length < pipe.minBatchSize) {\n\t\t\t\t\t\tsequentialFailureCount++;\n\t\t\t\t\t\tif (sequentialFailureCount >= 3) {\n\t\t\t\t\t\t\tlogger?.debug(`Not enough ${statusTarget} requests to move to next stage ${pipe.target.id}, stopping batch processing`);\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlogger?.debug(`Not moving ${statusTarget} requests to next stage ${pipe.target.id} because batch size ${batchRaw.length} is less than minimum size ${pipe.minBatchSize}`);\n\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tsequentialFailureCount = 0;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * The IDs for the entries we are sending to the next stage\n\t\t\t\t\t * target -- this may get reduced if we find there are already\n\t\t\t\t\t * jobs in the next stage that have the idempotentIDs of one of\n\t\t\t\t\t * these jobs\n\t\t\t\t\t */\n\t\t\t\t\tconst batchLocalIDs = new Set(batchRaw.map(function(entry) {\n\t\t\t\t\t\treturn(entry.id);\n\t\t\t\t\t}));\n\t\t\t\t\t/**\n\t\t\t\t\t * The outputs for the batch we are sending to the next stage\n\t\t\t\t\t */\n\t\t\t\t\tconst batchOutput = batchRaw.map(function(entry) {\n\t\t\t\t\t\treturn(entry.output);\n\t\t\t\t\t});\n\n\t\t\t\t\tlogger?.debug(`Moving batch of ${batchOutput.length} ${statusTarget} requests to next pipe`, pipe.target.id, '(input entry IDs:', Array.from(batchLocalIDs), '->', `${pipe.target.id}:${String(batchID)})`);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// There is no way for typescript to cleanly infer the type here, so we assert it.\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\t\t\t\tawait pipe.target.add(batchOutput as (UserRequest & UserResult)[], {\n\t\t\t\t\t\t\tid: batchID,\n\t\t\t\t\t\t\t/* Use the set of IDs as the idempotent IDs for the batch */\n\t\t\t\t\t\t\tidempotentKeys: batchLocalIDs\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tbatchID = ConvertStringToRequestID(crypto.randomUUID());\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (Errors.IdempotentExistsError.isInstance(error) && error.idempotentIDsFound) {\n\t\t\t\t\t\t\tlogger?.debug('Some of the jobs have already been added to the target queue, skipping those:', error.idempotentIDsFound.values());\n\t\t\t\t\t\t\tfor (const requestID of error.idempotentIDsFound) {\n\t\t\t\t\t\t\t\titerationTargetSeenRequestIDs.add(requestID);\n\t\t\t\t\t\t\t\tallTargetSeenRequestIDs.add(requestID);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * If we got some kind of other error adding these\n\t\t\t\t\t\t\t * items to the target queue runner, just skip them\n\t\t\t\t\t\t\t * and we will retry them on the next iteration\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tlogger?.error(`Failed to move completed batch to next stage ${pipe.target.id}, will try to create another batch without them:`, error);\n\n\t\t\t\t\t\t\tfor (const requestID of batchLocalIDs) {\n\t\t\t\t\t\t\t\tskipRequestIDs.add(requestID);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const requestID of batchLocalIDs) {\n\t\t\t\t\t\titerationTargetSeenRequestIDs.add(requestID);\n\t\t\t\t\t\tallTargetSeenRequestIDs.add(requestID);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/*\n\t\t\t\t * For every request we know the target has definitely seen, mark it\n\t\t\t\t * as moved for this pipe\n\t\t\t\t */\n\t\t\t\tfor (const requestID of allTargetSeenRequestIDs) {\n\t\t\t\t\tIncrRequestSentToPipes(requestID);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const request of requests) {\n\t\t\t\t\tlet shouldMarkAsMoved = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst output = getNextPipeRequestInput(request);\n\n\t\t\t\t\t\tif (output === null) {\n\t\t\t\t\t\t\tlogger?.debug(`Completed request with id ${String(request.id)} has no output -- next stage will not be run`);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlogger?.debug(`Moving ${statusTarget} request with id ${String(request.id)} to next pipe`, pipe.target.id);\n\t\t\t\t\t\t\t// There is no way for typescript to cleanly infer the type here, so we assert it.\n\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\t\t\t\t\tawait pipe.target.add(output as UserRequest & UserResult, { id: request.id });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tlogger?.error(`Failed to move completed request with id ${String(request.id)} to next stage:`, error);\n\t\t\t\t\t\tshouldMarkAsMoved = false;\n\t\t\t\t\t}\n\t\t\t\t\tif (shouldMarkAsMoved) {\n\t\t\t\t\t\tIncrRequestSentToPipes(request.id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst TotalPipes = pipes.length;\n\t\tfor (const request of allRequests) {\n\t\t\tconst sentCount = RequestSentToPipes.get(request.id) ?? 0;\n\t\t\tif (sentCount !== TotalPipes) {\n\t\t\t\tlogger?.debug(`${statusTarget} request with id ${String(request.id)} was only moved to ${sentCount} out of ${TotalPipes} pipes -- not marking as moved`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlogger?.debug(`Marking ${statusTarget} request with id ${String(request.id)} as moved`);\n\n\t\t\tawait this.queue.setStatus(request.id, 'moved', { oldStatus: statusTarget, by: this.workerID });\n\t\t}\n\n\t}\n\n\tasync maintain(): Promise<void> {\n\t\tconst logger = this.methodLogger('maintain');\n\n\t\tawait this.initialize();\n\n\t\t/*\n\t\t * Each worker should maintain its own lock\n\t\t */\n\t\ttry {\n\t\t\tawait this.maintainRunnerLock();\n\t\t} catch (error: unknown) {\n\t\t\tlogger?.debug('Failed to maintain runner lock:', error);\n\t\t}\n\n\t\tif (this.workers.id !== 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t/*\n\t\t * Only the worker with ID 0 should perform maintenance tasks on requests\n\t\t */\n\t\ttry {\n\t\t\tawait this.markStuckRequestsAsStuck();\n\t\t} catch (error: unknown) {\n\t\t\tlogger?.debug('Failed to mark stuck requests as stuck:', error);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.requeueFailedRequests();\n\t\t} catch (error: unknown) {\n\t\t\tlogger?.debug('Failed to requeue failed requests:', error);\n\t\t}\n\n\t\tfor (const pipeStatus of keetaAnchorPipeableQueueStatuses) {\n\t\t\ttry {\n\t\t\t\tawait this.moveCompletedToNextStage(pipeStatus);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.debug(`Failed to move ${pipeStatus} requests to next stage:`, error);\n\t\t\t}\n\t\t}\n\n\t\tfor (const pipe of this.pipes) {\n\t\t\ttry {\n\t\t\t\tif (pipe.exclusiveTarget === false) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tawait pipe.target.maintain();\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.debug(`Failed to maintain piped runner with ID ${pipe.target.id}:`, error);\n\t\t\t}\n\t\t}\n\n\t\tif (this.queue.maintain) {\n\t\t\ttry {\n\t\t\t\tawait this.queue.maintain();\n\t\t\t} catch (error: unknown) {\n\t\t\t\tlogger?.debug(`Failed to maintain queue storage driver with ID ${this.queue.id}`, error);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Pipe the the completed entries of this runner to another runner\n\t */\n\tpipe<T1, T2 extends JSONSerializable>(target: KeetaAnchorQueueRunner<UserResult, T1, QueueResult, T2>, options?: AdditionalPipeOptions): typeof target {\n\t\tthis.pipes.push({\n\t\t\t...options,\n\t\t\tisBatchPipe: false,\n\t\t\ttarget: target,\n\t\t\tacceptStatus: 'completed'\n\t\t});\n\t\treturn(target);\n\t}\n\n\tpipeFailed<T1, T2 extends JSONSerializable>(target: KeetaAnchorQueueRunner<UserRequest, T1, QueueResult, T2>, options?: AdditionalPipeOptions): typeof target {\n\t\tthis.pipes.push({\n\t\t\t...options,\n\t\t\tisBatchPipe: false,\n\t\t\ttarget: target,\n\t\t\tacceptStatus: 'failed_permanently'\n\t\t});\n\t\treturn(target);\n\t}\n\n\t/**\n\t * Pipe batches of completed entries from this runner to another runner\n\t */\n\tpipeBatch<T1, T2 extends JSONSerializable>(target: KeetaAnchorQueueRunner<UserResult[], T1, JSONSerializable, T2>, maxBatchSize = 100, minBatchSize = 1, options?: AdditionalPipeOptions): typeof target {\n\t\tthis.pipes.push({\n\t\t\t...options,\n\t\t\tisBatchPipe: true,\n\t\t\ttarget: target,\n\t\t\tminBatchSize: minBatchSize,\n\t\t\tmaxBatchSize: maxBatchSize,\n\t\t\tacceptStatus: 'completed'\n\t\t});\n\t\treturn(target);\n\t}\n\n\tpipeBatchFailed<T1, T2 extends JSONSerializable>(target: KeetaAnchorQueueRunner<UserRequest[], T1, JSONSerializable, T2>, maxBatchSize = 100, minBatchSize = 1, options?: AdditionalPipeOptions): typeof target {\n\t\tthis.pipes.push({\n\t\t\t...options,\n\t\t\tisBatchPipe: true,\n\t\t\ttarget: target,\n\t\t\tminBatchSize: minBatchSize,\n\t\t\tmaxBatchSize: maxBatchSize,\n\t\t\tacceptStatus: 'failed_permanently'\n\t\t});\n\t\treturn(target);\n\t}\n\n\tasync destroy(): Promise<void> {\n\t\tthis.methodLogger('destroy')?.debug('Destroying queue runner attached to queue', this.queue.id);\n\t}\n\n\tasync [Symbol.asyncDispose](): Promise<void> {\n\t\tawait this.destroy();\n\t}\n}\n\n/**\n * A KeetaAnchorQueueRunner for use when you want to process already\n * JSON-serializable data without any encoding/decoding needed\n */\nexport abstract class KeetaAnchorQueueRunnerJSON<UserRequest extends JSONSerializable = JSONSerializable, UserResult extends JSONSerializable = JSONSerializable> extends KeetaAnchorQueueRunner<UserRequest, UserResult, JSONSerializable, JSONSerializable> {\n\tprotected decodeRequest(request: JSONSerializable): UserRequest {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn(request as UserRequest);\n\t}\n\n\tprotected decodeResponse(response: JSONSerializable | null): UserResult | null {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn(response as UserResult | null);\n\t}\n\n\tprotected encodeRequest(request: JSONSerializable): JSONSerializable {\n\t\treturn(request);\n\t}\n\n\tprotected encodeResponse(response: JSONSerializable | null): JSONSerializable | null {\n\t\treturn(response);\n\t}\n}\n\n/**\n * A KeetaAnchorQueueRunnerJSON that takes a processor function\n * in the constructor -- this is mainly useful for testing\n */\nexport class KeetaAnchorQueueRunnerJSONConfigProc<UserRequest extends JSONSerializable = JSONSerializable, UserResult extends JSONSerializable = JSONSerializable> extends KeetaAnchorQueueRunnerJSON<UserRequest, UserResult> {\n\tprotected readonly processor: KeetaAnchorQueueRunner<UserRequest, UserResult>['processor'];\n\n\tconstructor(config: ConstructorParameters<typeof KeetaAnchorQueueRunner>[0] & {\n\t\tprocessor: KeetaAnchorQueueRunner<UserRequest, UserResult>['processor'];\n\t\tprocessorStuck?: KeetaAnchorQueueRunner<UserRequest, UserResult>['processorStuck'] | undefined;\n\t\tprocessorAborted?: KeetaAnchorQueueRunner<UserRequest, UserResult>['processorAborted'] | undefined;\n\t} & Partial<KeetaAnchorQueueRunnerConfigurationObject>) {\n\t\tsuper(config);\n\n\t\tconst { processor, processorStuck, processorAborted, ...parameters } = config;\n\n\t\tthis.processor = processor;\n\n\t\tif (processorStuck) {\n\t\t\tthis.processorStuck = processorStuck;\n\t\t}\n\t\tif (processorAborted) {\n\t\t\tthis.processorAborted = processorAborted;\n\t\t}\n\n\t\tthis.setConfiguration(parameters);\n\t}\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype _ignore_static_assert_memory = AssertNever<typeof KeetaAnchorQueueStorageDriverMemory<{ a: string; }, number> extends KeetaAnchorQueueStorageDriverConstructor<{ a: string; }, number> ? never : false>;\n"]}
|