@libp2p/utils 5.1.1-388d02b33 → 5.1.1-444d83751
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/peer-queue.d.ts +14 -0
- package/dist/src/peer-queue.d.ts.map +1 -0
- package/dist/src/peer-queue.js +16 -0
- package/dist/src/peer-queue.js.map +1 -0
- package/dist/src/queue/index.d.ts +122 -0
- package/dist/src/queue/index.d.ts.map +1 -0
- package/dist/src/queue/index.js +262 -0
- package/dist/src/queue/index.js.map +1 -0
- package/dist/src/queue/job.d.ts +25 -0
- package/dist/src/queue/job.d.ts.map +1 -0
- package/dist/src/queue/job.js +82 -0
- package/dist/src/queue/job.js.map +1 -0
- package/dist/src/queue/recipient.d.ts +10 -0
- package/dist/src/queue/recipient.d.ts.map +1 -0
- package/dist/src/queue/recipient.js +21 -0
- package/dist/src/queue/recipient.js.map +1 -0
- package/dist/src/tracked-list.d.ts +13 -0
- package/dist/src/tracked-list.d.ts.map +1 -0
- package/dist/src/tracked-list.js +11 -0
- package/dist/src/tracked-list.js.map +1 -0
- package/package.json +18 -11
- package/src/peer-queue.ts +24 -0
- package/src/queue/index.ts +365 -0
- package/src/queue/job.ts +105 -0
- package/src/queue/recipient.ts +26 -0
- package/src/tracked-list.ts +26 -0
- package/dist/src/peer-job-queue.d.ts +0 -42
- package/dist/src/peer-job-queue.d.ts.map +0 -1
- package/dist/src/peer-job-queue.js +0 -132
- package/dist/src/peer-job-queue.js.map +0 -1
- package/src/peer-job-queue.ts +0 -187
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Queue, type QueueAddOptions } from './queue/index.js';
|
|
2
|
+
import type { Job } from './queue/job.js';
|
|
3
|
+
import type { PeerId } from '@libp2p/interface';
|
|
4
|
+
export interface PeerQueueOptions extends QueueAddOptions {
|
|
5
|
+
peerId: PeerId;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Extends Queue to add support for querying queued jobs by peer id
|
|
9
|
+
*/
|
|
10
|
+
export declare class PeerQueue<JobReturnType = void> extends Queue<JobReturnType, PeerQueueOptions> {
|
|
11
|
+
has(peerId: PeerId): boolean;
|
|
12
|
+
find(peerId: PeerId): Job<PeerQueueOptions, JobReturnType> | undefined;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=peer-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-queue.d.ts","sourceRoot":"","sources":["../../src/peer-queue.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,qBAAa,SAAS,CAAC,aAAa,GAAG,IAAI,CAAE,SAAQ,KAAK,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzF,GAAG,CAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAI7B,IAAI,CAAE,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,gBAAgB,EAAE,aAAa,CAAC,GAAG,SAAS;CAKxE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import { Queue } from './queue/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Extends Queue to add support for querying queued jobs by peer id
|
|
5
|
+
*/
|
|
6
|
+
export class PeerQueue extends Queue {
|
|
7
|
+
has(peerId) {
|
|
8
|
+
return this.find(peerId) != null;
|
|
9
|
+
}
|
|
10
|
+
find(peerId) {
|
|
11
|
+
return this.queue.find(job => {
|
|
12
|
+
return peerId.equals(job.options.peerId);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=peer-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-queue.js","sourceRoot":"","sources":["../../src/peer-queue.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAE7D,OAAO,EAAE,KAAK,EAAwB,MAAM,kBAAkB,CAAA;AAQ9D;;GAEG;AACH,MAAM,OAAO,SAAgC,SAAQ,KAAsC;IACzF,GAAG,CAAE,MAAc;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAA;IAClC,CAAC;IAED,IAAI,CAAE,MAAc;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YAC3B,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { TypedEventEmitter } from '@libp2p/interface';
|
|
2
|
+
import { Job } from './job.js';
|
|
3
|
+
import type { AbortOptions, Metrics } from '@libp2p/interface';
|
|
4
|
+
export interface QueueAddOptions extends AbortOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Priority of operation. Operations with greater priority will be scheduled first.
|
|
7
|
+
*
|
|
8
|
+
* @default 0
|
|
9
|
+
*/
|
|
10
|
+
priority?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface QueueInit {
|
|
13
|
+
/**
|
|
14
|
+
* Concurrency limit.
|
|
15
|
+
*
|
|
16
|
+
* Minimum: `1`.
|
|
17
|
+
*
|
|
18
|
+
* @default Infinity
|
|
19
|
+
*/
|
|
20
|
+
concurrency?: number;
|
|
21
|
+
/**
|
|
22
|
+
* The name of the metric for the queue length
|
|
23
|
+
*/
|
|
24
|
+
metricName?: string;
|
|
25
|
+
/**
|
|
26
|
+
* An implementation of the libp2p Metrics interface
|
|
27
|
+
*/
|
|
28
|
+
metrics?: Metrics;
|
|
29
|
+
}
|
|
30
|
+
export type JobStatus = 'queued' | 'running' | 'errored' | 'complete';
|
|
31
|
+
export interface RunFunction<Options = AbortOptions, ReturnType = void> {
|
|
32
|
+
(opts?: Options): Promise<ReturnType>;
|
|
33
|
+
}
|
|
34
|
+
export interface JobMatcher<JobOptions extends QueueAddOptions = QueueAddOptions> {
|
|
35
|
+
(options?: Partial<JobOptions>): boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface QueueEvents<JobReturnType> {
|
|
38
|
+
'active': CustomEvent;
|
|
39
|
+
'idle': CustomEvent;
|
|
40
|
+
'empty': CustomEvent;
|
|
41
|
+
'add': CustomEvent;
|
|
42
|
+
'next': CustomEvent;
|
|
43
|
+
'completed': CustomEvent<JobReturnType>;
|
|
44
|
+
'error': CustomEvent<Error>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Heavily influence by `p-queue` with the following differences:
|
|
48
|
+
*
|
|
49
|
+
* 1. Items remain at the head of the queue while they are running so `queue.size` includes `queue.pending` items - this is so interested parties can join the results of a queue item while it is running
|
|
50
|
+
* 2. The options for a job are stored separately to the job in order for them to be modified while they are still in the queue
|
|
51
|
+
*/
|
|
52
|
+
export declare class Queue<JobReturnType = unknown, JobOptions extends QueueAddOptions = QueueAddOptions> extends TypedEventEmitter<QueueEvents<JobReturnType>> {
|
|
53
|
+
concurrency: number;
|
|
54
|
+
queue: Array<Job<JobOptions, JobReturnType>>;
|
|
55
|
+
private pending;
|
|
56
|
+
constructor(init?: QueueInit);
|
|
57
|
+
private tryToStartAnother;
|
|
58
|
+
private enqueue;
|
|
59
|
+
/**
|
|
60
|
+
* Adds a sync or async task to the queue. Always returns a promise.
|
|
61
|
+
*/
|
|
62
|
+
add(fn: RunFunction<JobOptions, JobReturnType>, options?: JobOptions): Promise<JobReturnType>;
|
|
63
|
+
/**
|
|
64
|
+
* Clear the queue
|
|
65
|
+
*/
|
|
66
|
+
clear(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Abort all jobs in the queue and clear it
|
|
69
|
+
*/
|
|
70
|
+
abort(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Can be called multiple times. Useful if you for example add additional items at a later time.
|
|
73
|
+
*
|
|
74
|
+
* @returns A promise that settles when the queue becomes empty.
|
|
75
|
+
*/
|
|
76
|
+
onEmpty(options?: AbortOptions): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* @returns A promise that settles when the queue size is less than the given
|
|
79
|
+
* limit: `queue.size < limit`.
|
|
80
|
+
*
|
|
81
|
+
* If you want to avoid having the queue grow beyond a certain size you can
|
|
82
|
+
* `await queue.onSizeLessThan()` before adding a new item.
|
|
83
|
+
*
|
|
84
|
+
* Note that this only limits the number of items waiting to start. There
|
|
85
|
+
* could still be up to `concurrency` jobs already running that this call does
|
|
86
|
+
* not include in its calculation.
|
|
87
|
+
*/
|
|
88
|
+
onSizeLessThan(limit: number, options?: AbortOptions): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* The difference with `.onEmpty` is that `.onIdle` guarantees that all work
|
|
91
|
+
* from the queue has finished. `.onEmpty` merely signals that the queue is
|
|
92
|
+
* empty, but it could mean that some promises haven't completed yet.
|
|
93
|
+
*
|
|
94
|
+
* @returns A promise that settles when the queue becomes empty, and all
|
|
95
|
+
* promises have completed; `queue.size === 0 && queue.pending === 0`.
|
|
96
|
+
*/
|
|
97
|
+
onIdle(options?: AbortOptions): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Size of the queue including running items
|
|
100
|
+
*/
|
|
101
|
+
get size(): number;
|
|
102
|
+
/**
|
|
103
|
+
* The number of queued items waiting to run.
|
|
104
|
+
*/
|
|
105
|
+
get queued(): number;
|
|
106
|
+
/**
|
|
107
|
+
* The number of items currently running.
|
|
108
|
+
*/
|
|
109
|
+
get running(): number;
|
|
110
|
+
/**
|
|
111
|
+
* Returns an async generator that makes it easy to iterate over the results
|
|
112
|
+
* of jobs added to the queue.
|
|
113
|
+
*
|
|
114
|
+
* The generator will end when the queue becomes idle, that is there are no
|
|
115
|
+
* jobs running and no jobs that have yet to run.
|
|
116
|
+
*
|
|
117
|
+
* If you need to keep the queue open indefinitely, consider using it-pushable
|
|
118
|
+
* instead.
|
|
119
|
+
*/
|
|
120
|
+
toGenerator(options?: AbortOptions): AsyncGenerator<JobReturnType, void, unknown>;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/queue/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAG5E,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE9D,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,SAAS;IACxB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAA;AAErE,MAAM,WAAW,WAAW,CAAC,OAAO,GAAG,YAAY,EAAE,UAAU,GAAG,IAAI;IACpE,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,UAAU,CAAC,UAAU,SAAS,eAAe,GAAG,eAAe;IAC9E,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAA;CACzC;AAED,MAAM,WAAW,WAAW,CAAC,aAAa;IACxC,QAAQ,EAAE,WAAW,CAAA;IACrB,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,WAAW,CAAA;IACnB,WAAW,EAAE,WAAW,CAAC,aAAa,CAAC,CAAA;IACvC,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;CAC5B;AAuBD;;;;;GAKG;AACH,qBAAa,KAAK,CAAC,aAAa,GAAG,OAAO,EAAE,UAAU,SAAS,eAAe,GAAG,eAAe,CAAE,SAAQ,iBAAiB,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IAC9I,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAA;IACnD,OAAO,CAAC,OAAO,CAAQ;gBAEV,IAAI,GAAE,SAAc;IAqBjC,OAAO,CAAC,iBAAiB;IA0DzB,OAAO,CAAC,OAAO;IAaf;;OAEG;IACG,GAAG,CAAE,EAAE,EAAE,WAAW,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;IAwBpG;;OAEG;IACH,KAAK,IAAK,IAAI;IAId;;OAEG;IACH,KAAK,IAAK,IAAI;IAQd;;;;OAIG;IACG,OAAO,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IASrD;;;;;;;;;;OAUG;IACG,cAAc,CAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3E;;;;;;;OAOG;IACG,MAAM,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IASpD;;OAEG;IACH,IAAI,IAAI,IAAK,MAAM,CAElB;IAED;;OAEG;IACH,IAAI,MAAM,IAAK,MAAM,CAEpB;IAED;;OAEG;IACH,IAAI,OAAO,IAAK,MAAM,CAErB;IAED;;;;;;;;;OASG;IACK,WAAW,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,aAAa,EAAE,IAAI,EAAE,OAAO,CAAC;CAuD3F"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { AbortError, CodeError, TypedEventEmitter } from '@libp2p/interface';
|
|
2
|
+
import { pushable } from 'it-pushable';
|
|
3
|
+
import { raceEvent } from 'race-event';
|
|
4
|
+
import { Job } from './job.js';
|
|
5
|
+
// Port of lower_bound from https://en.cppreference.com/w/cpp/algorithm/lower_bound
|
|
6
|
+
// Used to compute insertion index to keep queue sorted after insertion
|
|
7
|
+
function lowerBound(array, value, comparator) {
|
|
8
|
+
let first = 0;
|
|
9
|
+
let count = array.length;
|
|
10
|
+
while (count > 0) {
|
|
11
|
+
const step = Math.trunc(count / 2);
|
|
12
|
+
let it = first + step;
|
|
13
|
+
if (comparator(array[it], value) <= 0) {
|
|
14
|
+
first = ++it;
|
|
15
|
+
count -= step + 1;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
count = step;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return first;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Heavily influence by `p-queue` with the following differences:
|
|
25
|
+
*
|
|
26
|
+
* 1. Items remain at the head of the queue while they are running so `queue.size` includes `queue.pending` items - this is so interested parties can join the results of a queue item while it is running
|
|
27
|
+
* 2. The options for a job are stored separately to the job in order for them to be modified while they are still in the queue
|
|
28
|
+
*/
|
|
29
|
+
export class Queue extends TypedEventEmitter {
|
|
30
|
+
concurrency;
|
|
31
|
+
queue;
|
|
32
|
+
pending;
|
|
33
|
+
constructor(init = {}) {
|
|
34
|
+
super();
|
|
35
|
+
this.concurrency = init.concurrency ?? Number.POSITIVE_INFINITY;
|
|
36
|
+
this.pending = 0;
|
|
37
|
+
if (init.metricName != null) {
|
|
38
|
+
init.metrics?.registerMetricGroup(init.metricName, {
|
|
39
|
+
calculate: () => {
|
|
40
|
+
return {
|
|
41
|
+
size: this.queue.length,
|
|
42
|
+
running: this.pending,
|
|
43
|
+
queued: this.queue.length - this.pending
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
this.queue = [];
|
|
49
|
+
}
|
|
50
|
+
tryToStartAnother() {
|
|
51
|
+
if (this.size === 0) {
|
|
52
|
+
// do this in the microtask queue so all job recipients receive the
|
|
53
|
+
// result before the "empty" event fires
|
|
54
|
+
queueMicrotask(() => {
|
|
55
|
+
this.safeDispatchEvent('empty');
|
|
56
|
+
});
|
|
57
|
+
if (this.running === 0) {
|
|
58
|
+
// do this in the microtask queue so all job recipients receive the
|
|
59
|
+
// result before the "idle" event fires
|
|
60
|
+
queueMicrotask(() => {
|
|
61
|
+
this.safeDispatchEvent('idle');
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (this.pending < this.concurrency) {
|
|
67
|
+
let job;
|
|
68
|
+
for (const j of this.queue) {
|
|
69
|
+
if (j.status === 'queued') {
|
|
70
|
+
job = j;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (job == null) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
this.safeDispatchEvent('active');
|
|
78
|
+
this.pending++;
|
|
79
|
+
job.run()
|
|
80
|
+
.finally(() => {
|
|
81
|
+
// remove the job from the queue
|
|
82
|
+
for (let i = 0; i < this.queue.length; i++) {
|
|
83
|
+
if (this.queue[i] === job) {
|
|
84
|
+
this.queue.splice(i, 1);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.pending--;
|
|
89
|
+
this.tryToStartAnother();
|
|
90
|
+
this.safeDispatchEvent('next');
|
|
91
|
+
});
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
enqueue(job) {
|
|
97
|
+
if (this.queue[this.size - 1]?.priority >= job.priority) {
|
|
98
|
+
this.queue.push(job);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const index = lowerBound(this.queue, job, (a, b) => b.priority - a.priority);
|
|
102
|
+
this.queue.splice(index, 0, job);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Adds a sync or async task to the queue. Always returns a promise.
|
|
106
|
+
*/
|
|
107
|
+
async add(fn, options) {
|
|
108
|
+
options?.signal?.throwIfAborted();
|
|
109
|
+
const job = new Job(fn, options, options?.priority);
|
|
110
|
+
const p = job.join(options)
|
|
111
|
+
.then(result => {
|
|
112
|
+
this.safeDispatchEvent('completed', { detail: result });
|
|
113
|
+
return result;
|
|
114
|
+
})
|
|
115
|
+
.catch(err => {
|
|
116
|
+
this.safeDispatchEvent('error', { detail: err });
|
|
117
|
+
throw err;
|
|
118
|
+
});
|
|
119
|
+
this.enqueue(job);
|
|
120
|
+
this.safeDispatchEvent('add');
|
|
121
|
+
this.tryToStartAnother();
|
|
122
|
+
return p;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Clear the queue
|
|
126
|
+
*/
|
|
127
|
+
clear() {
|
|
128
|
+
this.queue.splice(0, this.queue.length);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Abort all jobs in the queue and clear it
|
|
132
|
+
*/
|
|
133
|
+
abort() {
|
|
134
|
+
this.queue.forEach(job => {
|
|
135
|
+
job.abort(new AbortError());
|
|
136
|
+
});
|
|
137
|
+
this.clear();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Can be called multiple times. Useful if you for example add additional items at a later time.
|
|
141
|
+
*
|
|
142
|
+
* @returns A promise that settles when the queue becomes empty.
|
|
143
|
+
*/
|
|
144
|
+
async onEmpty(options) {
|
|
145
|
+
// Instantly resolve if the queue is empty
|
|
146
|
+
if (this.size === 0) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
await raceEvent(this, 'empty', options?.signal);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* @returns A promise that settles when the queue size is less than the given
|
|
153
|
+
* limit: `queue.size < limit`.
|
|
154
|
+
*
|
|
155
|
+
* If you want to avoid having the queue grow beyond a certain size you can
|
|
156
|
+
* `await queue.onSizeLessThan()` before adding a new item.
|
|
157
|
+
*
|
|
158
|
+
* Note that this only limits the number of items waiting to start. There
|
|
159
|
+
* could still be up to `concurrency` jobs already running that this call does
|
|
160
|
+
* not include in its calculation.
|
|
161
|
+
*/
|
|
162
|
+
async onSizeLessThan(limit, options) {
|
|
163
|
+
// Instantly resolve if the queue is empty.
|
|
164
|
+
if (this.size < limit) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
await raceEvent(this, 'next', options?.signal, {
|
|
168
|
+
filter: () => this.size < limit
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The difference with `.onEmpty` is that `.onIdle` guarantees that all work
|
|
173
|
+
* from the queue has finished. `.onEmpty` merely signals that the queue is
|
|
174
|
+
* empty, but it could mean that some promises haven't completed yet.
|
|
175
|
+
*
|
|
176
|
+
* @returns A promise that settles when the queue becomes empty, and all
|
|
177
|
+
* promises have completed; `queue.size === 0 && queue.pending === 0`.
|
|
178
|
+
*/
|
|
179
|
+
async onIdle(options) {
|
|
180
|
+
// Instantly resolve if none pending and if nothing else is queued
|
|
181
|
+
if (this.pending === 0 && this.size === 0) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
await raceEvent(this, 'idle', options?.signal);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Size of the queue including running items
|
|
188
|
+
*/
|
|
189
|
+
get size() {
|
|
190
|
+
return this.queue.length;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* The number of queued items waiting to run.
|
|
194
|
+
*/
|
|
195
|
+
get queued() {
|
|
196
|
+
return this.queue.length - this.pending;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The number of items currently running.
|
|
200
|
+
*/
|
|
201
|
+
get running() {
|
|
202
|
+
return this.pending;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Returns an async generator that makes it easy to iterate over the results
|
|
206
|
+
* of jobs added to the queue.
|
|
207
|
+
*
|
|
208
|
+
* The generator will end when the queue becomes idle, that is there are no
|
|
209
|
+
* jobs running and no jobs that have yet to run.
|
|
210
|
+
*
|
|
211
|
+
* If you need to keep the queue open indefinitely, consider using it-pushable
|
|
212
|
+
* instead.
|
|
213
|
+
*/
|
|
214
|
+
async *toGenerator(options) {
|
|
215
|
+
options?.signal?.throwIfAborted();
|
|
216
|
+
const stream = pushable({
|
|
217
|
+
objectMode: true
|
|
218
|
+
});
|
|
219
|
+
const cleanup = (err) => {
|
|
220
|
+
if (err != null) {
|
|
221
|
+
this.abort();
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
this.clear();
|
|
225
|
+
}
|
|
226
|
+
stream.end(err);
|
|
227
|
+
};
|
|
228
|
+
const onQueueJobComplete = (evt) => {
|
|
229
|
+
if (evt.detail != null) {
|
|
230
|
+
stream.push(evt.detail);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
const onQueueError = (evt) => {
|
|
234
|
+
cleanup(evt.detail);
|
|
235
|
+
};
|
|
236
|
+
const onQueueIdle = () => {
|
|
237
|
+
cleanup();
|
|
238
|
+
};
|
|
239
|
+
// clear the queue and throw if the query is aborted
|
|
240
|
+
const onSignalAbort = () => {
|
|
241
|
+
cleanup(new CodeError('Queue aborted', 'ERR_QUEUE_ABORTED'));
|
|
242
|
+
};
|
|
243
|
+
// add listeners
|
|
244
|
+
this.addEventListener('completed', onQueueJobComplete);
|
|
245
|
+
this.addEventListener('error', onQueueError);
|
|
246
|
+
this.addEventListener('idle', onQueueIdle);
|
|
247
|
+
options?.signal?.addEventListener('abort', onSignalAbort);
|
|
248
|
+
try {
|
|
249
|
+
yield* stream;
|
|
250
|
+
}
|
|
251
|
+
finally {
|
|
252
|
+
// remove listeners
|
|
253
|
+
this.removeEventListener('completed', onQueueJobComplete);
|
|
254
|
+
this.removeEventListener('error', onQueueError);
|
|
255
|
+
this.removeEventListener('idle', onQueueIdle);
|
|
256
|
+
options?.signal?.removeEventListener('abort', onSignalAbort);
|
|
257
|
+
// empty the queue for when the user has broken out of a loop early
|
|
258
|
+
cleanup();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/queue/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { JobRecipient } from './recipient.js';
|
|
2
|
+
import type { JobStatus } from './index.js';
|
|
3
|
+
import type { AbortOptions } from '@libp2p/interface';
|
|
4
|
+
export interface JobTimeline {
|
|
5
|
+
created: number;
|
|
6
|
+
started?: number;
|
|
7
|
+
finished?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class Job<JobOptions extends AbortOptions = AbortOptions, JobReturnType = unknown> {
|
|
10
|
+
id: string;
|
|
11
|
+
fn: (options: JobOptions) => Promise<JobReturnType>;
|
|
12
|
+
options: JobOptions;
|
|
13
|
+
priority: number;
|
|
14
|
+
recipients: Array<JobRecipient<JobReturnType>>;
|
|
15
|
+
status: JobStatus;
|
|
16
|
+
readonly timeline: JobTimeline;
|
|
17
|
+
private readonly controller;
|
|
18
|
+
constructor(fn: (options: JobOptions) => Promise<JobReturnType>, options: any, priority?: number);
|
|
19
|
+
abort(err: Error): void;
|
|
20
|
+
onAbort(): void;
|
|
21
|
+
join(options?: AbortOptions): Promise<JobReturnType>;
|
|
22
|
+
run(): Promise<void>;
|
|
23
|
+
cleanup(): void;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=job.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../../../src/queue/job.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AASrD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,GAAG,CAAE,UAAU,SAAS,YAAY,GAAG,YAAY,EAAE,aAAa,GAAG,OAAO;IAChF,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;IACnD,OAAO,EAAE,UAAU,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAA;IAC9C,MAAM,EAAE,SAAS,CAAA;IACxB,SAAgB,QAAQ,EAAE,WAAW,CAAA;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;gBAE/B,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAE,MAAU;IAiBpG,KAAK,CAAE,GAAG,EAAE,KAAK,GAAG,IAAI;IAIxB,OAAO,IAAK,IAAI;IAWV,IAAI,CAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IASzD,GAAG,IAAK,OAAO,CAAC,IAAI,CAAC;IA6B3B,OAAO,IAAK,IAAI;CAKjB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { AbortError, setMaxListeners } from '@libp2p/interface';
|
|
2
|
+
import { raceSignal } from 'race-signal';
|
|
3
|
+
import { JobRecipient } from './recipient.js';
|
|
4
|
+
/**
|
|
5
|
+
* Returns a random string
|
|
6
|
+
*/
|
|
7
|
+
function randomId() {
|
|
8
|
+
return `${(parseInt(String(Math.random() * 1e9), 10)).toString()}${Date.now()}`;
|
|
9
|
+
}
|
|
10
|
+
export class Job {
|
|
11
|
+
id;
|
|
12
|
+
fn;
|
|
13
|
+
options;
|
|
14
|
+
priority;
|
|
15
|
+
recipients;
|
|
16
|
+
status;
|
|
17
|
+
timeline;
|
|
18
|
+
controller;
|
|
19
|
+
constructor(fn, options, priority = 0) {
|
|
20
|
+
this.id = randomId();
|
|
21
|
+
this.status = 'queued';
|
|
22
|
+
this.fn = fn;
|
|
23
|
+
this.priority = priority;
|
|
24
|
+
this.options = options;
|
|
25
|
+
this.recipients = [];
|
|
26
|
+
this.timeline = {
|
|
27
|
+
created: Date.now()
|
|
28
|
+
};
|
|
29
|
+
this.controller = new AbortController();
|
|
30
|
+
setMaxListeners(Infinity, this.controller.signal);
|
|
31
|
+
this.onAbort = this.onAbort.bind(this);
|
|
32
|
+
}
|
|
33
|
+
abort(err) {
|
|
34
|
+
this.controller.abort(err);
|
|
35
|
+
}
|
|
36
|
+
onAbort() {
|
|
37
|
+
const allAborted = this.recipients.reduce((acc, curr) => {
|
|
38
|
+
return acc && (curr.signal?.aborted === true);
|
|
39
|
+
}, true);
|
|
40
|
+
// if all recipients have aborted the job, actually abort the job
|
|
41
|
+
if (allAborted) {
|
|
42
|
+
this.controller.abort(new AbortError());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async join(options = {}) {
|
|
46
|
+
const recipient = new JobRecipient((new Error('where')).stack, options.signal);
|
|
47
|
+
this.recipients.push(recipient);
|
|
48
|
+
options.signal?.addEventListener('abort', this.onAbort);
|
|
49
|
+
return recipient.deferred.promise;
|
|
50
|
+
}
|
|
51
|
+
async run() {
|
|
52
|
+
this.status = 'running';
|
|
53
|
+
this.timeline.started = Date.now();
|
|
54
|
+
try {
|
|
55
|
+
this.controller.signal.throwIfAborted();
|
|
56
|
+
const result = await raceSignal(this.fn({
|
|
57
|
+
...(this.options ?? {}),
|
|
58
|
+
signal: this.controller.signal
|
|
59
|
+
}), this.controller.signal);
|
|
60
|
+
this.recipients.forEach(recipient => {
|
|
61
|
+
recipient.deferred.resolve(result);
|
|
62
|
+
});
|
|
63
|
+
this.status = 'complete';
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
this.recipients.forEach(recipient => {
|
|
67
|
+
recipient.deferred.reject(err);
|
|
68
|
+
});
|
|
69
|
+
this.status = 'errored';
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
this.timeline.finished = Date.now();
|
|
73
|
+
this.cleanup();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
cleanup() {
|
|
77
|
+
this.recipients.forEach(recipient => {
|
|
78
|
+
recipient.signal?.removeEventListener('abort', this.onAbort);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=job.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.js","sourceRoot":"","sources":["../../../src/queue/job.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DeferredPromise } from 'p-defer';
|
|
2
|
+
export declare class JobRecipient<JobReturnType> {
|
|
3
|
+
deferred: DeferredPromise<JobReturnType>;
|
|
4
|
+
signal?: AbortSignal;
|
|
5
|
+
where?: string;
|
|
6
|
+
constructor(where?: string, signal?: AbortSignal);
|
|
7
|
+
onAbort(): void;
|
|
8
|
+
cleanup(): void;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=recipient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipient.d.ts","sourceRoot":"","sources":["../../../src/queue/recipient.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,qBAAa,YAAY,CAAC,aAAa;IAC9B,QAAQ,EAAE,eAAe,CAAC,aAAa,CAAC,CAAA;IACxC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;gBAER,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW;IASjD,OAAO,IAAK,IAAI;IAIhB,OAAO,IAAK,IAAI;CAGjB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AbortError } from '@libp2p/interface';
|
|
2
|
+
import pDefer from 'p-defer';
|
|
3
|
+
export class JobRecipient {
|
|
4
|
+
deferred;
|
|
5
|
+
signal;
|
|
6
|
+
where;
|
|
7
|
+
constructor(where, signal) {
|
|
8
|
+
this.signal = signal;
|
|
9
|
+
this.deferred = pDefer();
|
|
10
|
+
this.where = where;
|
|
11
|
+
this.onAbort = this.onAbort.bind(this);
|
|
12
|
+
this.signal?.addEventListener('abort', this.onAbort);
|
|
13
|
+
}
|
|
14
|
+
onAbort() {
|
|
15
|
+
this.deferred.reject(new AbortError());
|
|
16
|
+
}
|
|
17
|
+
cleanup() {
|
|
18
|
+
this.signal?.removeEventListener('abort', this.onAbort);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=recipient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipient.js","sourceRoot":"","sources":["../../../src/queue/recipient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,MAAM,MAAM,SAAS,CAAA;AAG5B,MAAM,OAAO,YAAY;IAChB,QAAQ,CAAgC;IACxC,MAAM,CAAc;IACpB,KAAK,CAAS;IAErB,YAAa,KAAc,EAAE,MAAoB;QAC/C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,QAAQ,GAAG,MAAM,EAAE,CAAA;QACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAElB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACtD,CAAC;IAED,OAAO;QACL,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC,CAAA;IACxC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACzD,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Metrics } from '@libp2p/interface';
|
|
2
|
+
export interface CreateTrackedListInit {
|
|
3
|
+
/**
|
|
4
|
+
* The metric name to use
|
|
5
|
+
*/
|
|
6
|
+
name: string;
|
|
7
|
+
/**
|
|
8
|
+
* A metrics implementation
|
|
9
|
+
*/
|
|
10
|
+
metrics?: Metrics;
|
|
11
|
+
}
|
|
12
|
+
export declare function trackedList<V>(config: CreateTrackedListInit): V[];
|
|
13
|
+
//# sourceMappingURL=tracked-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracked-list.d.ts","sourceRoot":"","sources":["../../src/tracked-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAEhD,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,WAAW,CAAE,CAAC,EAAG,MAAM,EAAE,qBAAqB,GAAG,CAAC,EAAE,CAWnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracked-list.js","sourceRoot":"","sources":["../../src/tracked-list.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,WAAW,CAAM,MAA6B;IAC5D,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;IAChC,MAAM,IAAI,GAAQ,EAAE,CAAA;IAEpB,OAAO,EAAE,cAAc,CAAC,IAAI,EAAE;QAC5B,SAAS,EAAE,GAAG,EAAE;YACd,OAAO,IAAI,CAAC,MAAM,CAAA;QACpB,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,IAAI,CAAA;AACb,CAAC"}
|