@neofinancial/chrono 0.1.0 → 0.1.2
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/README.md +187 -0
- package/build/chrono.js +2 -2
- package/build/chrono.js.map +1 -1
- package/build/datastore.d.ts +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.js.map +1 -1
- package/build/processors/create-processor.d.ts +1 -0
- package/build/processors/create-processor.js +1 -12
- package/build/processors/create-processor.js.map +1 -1
- package/build/processors/processor.d.ts +1 -1
- package/build/processors/simple-processor.d.ts +13 -21
- package/build/processors/simple-processor.js +33 -36
- package/build/processors/simple-processor.js.map +1 -1
- package/package.json +9 -3
- package/build/scheduler.d.ts +0 -9
- package/build/scheduler.js +0 -21
- package/build/scheduler.js.map +0 -1
- package/build/task.d.ts +0 -33
- package/build/task.js +0 -10
- package/build/task.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# @neofinancial/chrono
|
|
2
|
+
|
|
3
|
+
⚠️ This project is pre-alpha, and not ready for production use. ⚠️
|
|
4
|
+
|
|
5
|
+
A TypeScript task scheduling and processing system for reliable background job processing.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Type-safe task processing**: Define strongly typed tasks and handlers
|
|
10
|
+
- **Flexible scheduling**: Schedule tasks for immediate or future execution
|
|
11
|
+
- **Configurable retry strategies**: Linear and exponential backoff with optional jitter
|
|
12
|
+
- **Idempotency support**: Prevent duplicate task processing
|
|
13
|
+
- **Event-based architecture**: Track task lifecycle events
|
|
14
|
+
- **Datastore agnostic**: Works with any compatible datastore implementation
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @neofinancial/chrono
|
|
20
|
+
# or
|
|
21
|
+
pnpm add @neofinancial/chrono
|
|
22
|
+
# or
|
|
23
|
+
yarn add @neofinancial/chrono
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Basic Usage
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { Chrono } from "@neofinancial/chrono";
|
|
30
|
+
|
|
31
|
+
// Define your task types
|
|
32
|
+
type TaskMapping = {
|
|
33
|
+
"send-email": { to: string; subject: string; body: string };
|
|
34
|
+
"process-payment": { userId: string; amount: number };
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// You'll need a datastore implementation
|
|
38
|
+
// See @neofinancial/chrono-memory-datastore or @neofinancial/chrono-mongo-datastore
|
|
39
|
+
const datastore = /* your datastore instance */;
|
|
40
|
+
|
|
41
|
+
// Initialize Chrono with the datastore
|
|
42
|
+
const chrono = new Chrono<TaskMapping, undefined>(datastore);
|
|
43
|
+
|
|
44
|
+
// Register task handlers
|
|
45
|
+
chrono.registerTaskHandler({
|
|
46
|
+
kind: "send-email",
|
|
47
|
+
handler: async (task) => {
|
|
48
|
+
// Logic to send an email
|
|
49
|
+
console.log(
|
|
50
|
+
`Sending email to ${task.data.to} with subject "${task.data.subject}"`
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
backoffStrategyOptions: {
|
|
54
|
+
type: "linear",
|
|
55
|
+
baseDelayMs: 1000,
|
|
56
|
+
incrementMs: 2000,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
chrono.registerTaskHandler({
|
|
61
|
+
kind: "process-payment",
|
|
62
|
+
handler: async (task) => {
|
|
63
|
+
// Logic to process payment
|
|
64
|
+
console.log(
|
|
65
|
+
`Processing payment of ${task.data.amount} for user ${task.data.userId}`
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
backoffStrategyOptions: {
|
|
69
|
+
type: "exponential",
|
|
70
|
+
baseDelayMs: 1000,
|
|
71
|
+
maxDelayMs: 60000,
|
|
72
|
+
jitter: "full",
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Start Chrono
|
|
77
|
+
await chrono.start();
|
|
78
|
+
|
|
79
|
+
// Schedule tasks
|
|
80
|
+
await chrono.scheduleTask({
|
|
81
|
+
kind: "send-email",
|
|
82
|
+
when: new Date(), // run immediately
|
|
83
|
+
data: {
|
|
84
|
+
to: "user@example.com",
|
|
85
|
+
subject: "Welcome!",
|
|
86
|
+
body: "Welcome to our application!",
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Schedule a task for the future
|
|
91
|
+
const thirtyMinutesFromNow = new Date(Date.now() + 30 * 60 * 1000);
|
|
92
|
+
|
|
93
|
+
await chrono.scheduleTask({
|
|
94
|
+
kind: "process-payment",
|
|
95
|
+
when: thirtyMinutesFromNow, // run 30 minutes from now
|
|
96
|
+
data: {
|
|
97
|
+
userId: "user-123",
|
|
98
|
+
amount: 99.99,
|
|
99
|
+
},
|
|
100
|
+
idempotencyKey: "payment-123", // Prevents duplicate processing
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// For cleanup when shutting down
|
|
104
|
+
process.on("SIGINT", async () => {
|
|
105
|
+
await chrono.stop();
|
|
106
|
+
process.exit(0);
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Datastore Implementations
|
|
111
|
+
|
|
112
|
+
Chrono requires a datastore implementation to persist and manage tasks. Available implementations:
|
|
113
|
+
|
|
114
|
+
- **[@neofinancial/chrono-memory-datastore](https://www.npmjs.com/package/@neofinancial/chrono-memory-datastore)**: In-memory datastore for development and testing
|
|
115
|
+
- **[@neofinancial/chrono-mongo-datastore](https://www.npmjs.com/package/@neofinancial/chrono-mongo-datastore)**: MongoDB datastore for production use
|
|
116
|
+
|
|
117
|
+
## Events
|
|
118
|
+
|
|
119
|
+
### Chrono Instance Events
|
|
120
|
+
|
|
121
|
+
- `ready` - Emitted when all processors are started as a result of calling `chrono.start()`
|
|
122
|
+
- `close` - Emitted after stopping all processors as a result of calling `chrono.stop()`
|
|
123
|
+
- `stop:failed` - Emitted if any processor fails to stop within the exit timeout
|
|
124
|
+
|
|
125
|
+
### Processor Instance Events
|
|
126
|
+
|
|
127
|
+
**Task related events**
|
|
128
|
+
|
|
129
|
+
- `task:claimed` - Emitted when a task is claimed
|
|
130
|
+
- `task:completed` - Emitted when a task is successfully processed
|
|
131
|
+
- `task:completion:failed` - Emitted when the task fails to mark as completed
|
|
132
|
+
- `task:retry:requested` - Emitted when a task will be retried after an error
|
|
133
|
+
- `task:failed` - Emitted when max retries is reached after errors
|
|
134
|
+
|
|
135
|
+
## Retry Strategies
|
|
136
|
+
|
|
137
|
+
Chrono supports configurable retry strategies:
|
|
138
|
+
|
|
139
|
+
### No Backoff
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
{
|
|
143
|
+
type: "none";
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Fixed Backoff
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
{
|
|
151
|
+
type: "fixed",
|
|
152
|
+
delayMs: 1000 // Fixed delay in milliseconds
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Linear Backoff
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
{
|
|
160
|
+
type: "linear",
|
|
161
|
+
baseDelayMs: 1000, // Initial delay
|
|
162
|
+
incrementMs: 2000, // Amount to add each retry
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Exponential Backoff
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
{
|
|
170
|
+
type: "exponential",
|
|
171
|
+
baseDelayMs: 1000, // Initial delay
|
|
172
|
+
maxDelayMs: 60000, // Maximum delay cap
|
|
173
|
+
jitter: "full", // Optional: "none" | "full" | "equal"
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## TypeScript Support
|
|
178
|
+
|
|
179
|
+
This package is written in TypeScript and provides full type safety for your task definitions and handlers.
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
MIT
|
|
184
|
+
|
|
185
|
+
## Contributing
|
|
186
|
+
|
|
187
|
+
This package is part of the [chrono monorepo](https://github.com/neofinancial/chrono). Please see the main repository for contributing guidelines.
|
package/build/chrono.js
CHANGED
|
@@ -33,10 +33,9 @@ class Chrono extends node_stream_1.EventEmitter {
|
|
|
33
33
|
const stopPromises = Array.from(this.processors.values()).map((processor) => processor.stop());
|
|
34
34
|
try {
|
|
35
35
|
await (0, promise_utils_1.promiseWithTimeout)(Promise.all(stopPromises), this.exitTimeoutMs);
|
|
36
|
-
this.emit('stopped', { timestamp: new Date() });
|
|
37
36
|
}
|
|
38
37
|
catch (error) {
|
|
39
|
-
this.emit('stop
|
|
38
|
+
this.emit('stop:failed', { error, timestamp: new Date() });
|
|
40
39
|
}
|
|
41
40
|
finally {
|
|
42
41
|
this.emit('close', { timestamp: new Date() });
|
|
@@ -63,6 +62,7 @@ class Chrono extends node_stream_1.EventEmitter {
|
|
|
63
62
|
kind: input.kind,
|
|
64
63
|
datastore: this.datastore,
|
|
65
64
|
handler: input.handler,
|
|
65
|
+
backoffStrategyOptions: input.backoffStrategyOptions,
|
|
66
66
|
configuration: input.processorConfiguration,
|
|
67
67
|
});
|
|
68
68
|
this.processors.set(input.kind, processor);
|
package/build/chrono.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chrono.js","sourceRoot":"","sources":["../src/chrono.ts"],"names":[],"mappings":";;;AAAA,6CAA2C;AAI3C,6CAA+D;AAE/D,yDAA2D;AAiB3D;;;;;;;;;;GAUG;AAEH,MAAa,MAA8D,SAAQ,0BAAY;IACrF,SAAS,CAA2C;IACpD,UAAU,GAAsE,IAAI,GAAG,EAAE,CAAC;IAEzF,aAAa,GAAG,MAAM,CAAC;IAEhC,YAAY,SAAmD;QAC7D,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAE/F,IAAI,CAAC;YACH,MAAM,IAAA,kCAAkB,EAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"chrono.js","sourceRoot":"","sources":["../src/chrono.ts"],"names":[],"mappings":";;;AAAA,6CAA2C;AAI3C,6CAA+D;AAE/D,yDAA2D;AAiB3D;;;;;;;;;;GAUG;AAEH,MAAa,MAA8D,SAAQ,0BAAY;IACrF,SAAS,CAA2C;IACpD,UAAU,GAAsE,IAAI,GAAG,EAAE,CAAC;IAEzF,aAAa,GAAG,MAAM,CAAC;IAEhC,YAAY,SAAmD;QAC7D,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAE/F,IAAI,CAAC;YACH,MAAM,IAAA,kCAAkB,EAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,YAAY,CACvB,KAA2E;QAE3E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;YACzC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;SACzC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,UAAU,CACrB,MAAc;QAEd,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAW,MAAM,CAAC,CAAC;QAE3D,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,mBAAmB,CACxB,KAAgE;QAEhE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,SAAS,GAAG,IAAA,4BAAe,EAAC;YAChC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;YACpD,aAAa,EAAE,KAAK,CAAC,sBAAsB;SAC5C,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAE3C,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAxED,wBAwEC"}
|
package/build/datastore.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export interface Datastore<TaskMapping extends TaskMappingBase, DatastoreOptions
|
|
|
57
57
|
delete<TaskKind extends keyof TaskMapping>(taskId: string, options?: DeleteOptions): Promise<Task<TaskKind, TaskMapping[TaskKind]> | undefined>;
|
|
58
58
|
delete<TaskKind extends keyof TaskMapping>(key: DeleteByIdempotencyKeyInput<TaskKind>, options?: DeleteOptions): Promise<Task<TaskKind, TaskMapping[TaskKind]> | undefined>;
|
|
59
59
|
claim<TaskKind extends Extract<keyof TaskMapping, string>>(input: ClaimTaskInput<TaskKind>): Promise<Task<TaskKind, TaskMapping[TaskKind]> | undefined>;
|
|
60
|
-
|
|
60
|
+
retry<TaskKind extends keyof TaskMapping>(taskId: string, retryAt: Date): Promise<Task<TaskKind, TaskMapping[TaskKind]>>;
|
|
61
61
|
complete<TaskKind extends keyof TaskMapping>(taskId: string): Promise<Task<TaskKind, TaskMapping[TaskKind]>>;
|
|
62
62
|
fail<TaskKind extends keyof TaskMapping>(taskId: string): Promise<Task<TaskKind, TaskMapping[TaskKind]>>;
|
|
63
63
|
}
|
package/build/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Chrono, type ScheduleTaskInput, type TaskMappingBase } from './chrono';
|
|
2
|
-
export { TaskStatus, type ClaimTaskInput, type Datastore, type ScheduleInput, type Task, type DeleteInput, type DeleteOptions, type DeleteByIdempotencyKeyInput } from './datastore';
|
|
2
|
+
export { TaskStatus, type ClaimTaskInput, type Datastore, type ScheduleInput, type Task, type DeleteInput, type DeleteOptions, type DeleteByIdempotencyKeyInput, } from './datastore';
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAgF;AAAvE,gGAAA,MAAM,OAAA;AACf,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAgF;AAAvE,gGAAA,MAAM,OAAA;AACf,yCASqB;AARnB,uGAAA,UAAU,OAAA"}
|
|
@@ -9,6 +9,7 @@ export type ProcessorConfiguration = {
|
|
|
9
9
|
idleIntervalMs?: number;
|
|
10
10
|
taskHandlerTimeoutMs?: number;
|
|
11
11
|
taskHandlerMaxRetries?: number;
|
|
12
|
+
processLoopRetryIntervalMs?: number;
|
|
12
13
|
};
|
|
13
14
|
export type CreateProcessorInput<TaskKind extends keyof TaskMapping, TaskMapping extends TaskMappingBase, DatastoreOptions> = {
|
|
14
15
|
kind: TaskKind;
|
|
@@ -6,17 +6,6 @@ const simple_processor_1 = require("./simple-processor");
|
|
|
6
6
|
function createProcessor(input) {
|
|
7
7
|
const backoffStrategy = (0, backoff_strategy_1.backoffStrategyFactory)(input.backoffStrategyOptions);
|
|
8
8
|
// add more processors here
|
|
9
|
-
return new simple_processor_1.SimpleProcessor(
|
|
10
|
-
datastore: input.datastore,
|
|
11
|
-
kind: input.kind,
|
|
12
|
-
handler: input.handler,
|
|
13
|
-
maxConcurrency: input.configuration?.maxConcurrency,
|
|
14
|
-
backoffStrategy,
|
|
15
|
-
claimIntervalMs: input.configuration?.claimIntervalMs,
|
|
16
|
-
idleIntervalMs: input.configuration?.idleIntervalMs,
|
|
17
|
-
taskHandlerTimeoutMs: input.configuration?.taskHandlerTimeoutMs,
|
|
18
|
-
claimStaleTimeoutMs: input.configuration?.claimStaleTimeoutMs,
|
|
19
|
-
taskHandlerMaxRetries: input.configuration?.taskHandlerMaxRetries,
|
|
20
|
-
});
|
|
9
|
+
return new simple_processor_1.SimpleProcessor(input.datastore, input.kind, input.handler, backoffStrategy, input.configuration);
|
|
21
10
|
}
|
|
22
11
|
//# sourceMappingURL=create-processor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-processor.js","sourceRoot":"","sources":["../../src/processors/create-processor.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"create-processor.js","sourceRoot":"","sources":["../../src/processors/create-processor.ts"],"names":[],"mappings":";;AA4BA,0CAcC;AAxCD,0DAA0F;AAE1F,yDAAqD;AAwBrD,SAAgB,eAAe,CAI7B,KAAoE;IACpE,MAAM,eAAe,GAAG,IAAA,yCAAsB,EAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC7E,2BAA2B;IAC3B,OAAO,IAAI,kCAAe,CACxB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,OAAO,EACb,eAAe,EACf,KAAK,CAAC,aAAa,CACpB,CAAC;AACJ,CAAC"}
|
|
@@ -14,7 +14,7 @@ export type ProcessorEvents<TaskKind extends keyof TaskMapping, TaskMapping exte
|
|
|
14
14
|
error: Error;
|
|
15
15
|
timestamp: Date;
|
|
16
16
|
}];
|
|
17
|
-
'task:
|
|
17
|
+
'task:retry:requested': [{
|
|
18
18
|
task: Task<TaskKind, TaskMapping[TaskKind]>;
|
|
19
19
|
error: Error;
|
|
20
20
|
timestamp: Date;
|
|
@@ -3,32 +3,24 @@ import type { BackoffStrategy } from '../backoff-strategy';
|
|
|
3
3
|
import type { TaskMappingBase } from '../chrono';
|
|
4
4
|
import type { Datastore, Task } from '../datastore';
|
|
5
5
|
import type { Processor, ProcessorEvents } from './processor';
|
|
6
|
-
type SimpleProcessorConfig
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
idleIntervalMs?: number;
|
|
15
|
-
taskHandlerTimeoutMs?: number;
|
|
16
|
-
taskHandlerMaxRetries?: number;
|
|
6
|
+
type SimpleProcessorConfig = {
|
|
7
|
+
maxConcurrency: number;
|
|
8
|
+
claimIntervalMs: number;
|
|
9
|
+
claimStaleTimeoutMs: number;
|
|
10
|
+
idleIntervalMs: number;
|
|
11
|
+
taskHandlerTimeoutMs: number;
|
|
12
|
+
taskHandlerMaxRetries: number;
|
|
13
|
+
processLoopRetryIntervalMs: number;
|
|
17
14
|
};
|
|
18
15
|
export declare class SimpleProcessor<TaskKind extends Extract<keyof TaskMapping, string>, TaskMapping extends TaskMappingBase, DatastoreOptions> extends EventEmitter<ProcessorEvents<TaskKind, TaskMapping>> implements Processor<TaskKind, TaskMapping> {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
private maxConcurrency;
|
|
16
|
+
private datastore;
|
|
17
|
+
private taskKind;
|
|
18
|
+
private handler;
|
|
23
19
|
private backOffStrategy;
|
|
24
|
-
|
|
25
|
-
readonly claimStaleTimeoutMs: number;
|
|
26
|
-
readonly idleIntervalMs: number;
|
|
27
|
-
readonly taskHandlerTimeoutMs: number;
|
|
28
|
-
readonly taskHandlerMaxRetries: number;
|
|
20
|
+
private config;
|
|
29
21
|
private exitChannels;
|
|
30
22
|
private stopRequested;
|
|
31
|
-
constructor(
|
|
23
|
+
constructor(datastore: Datastore<TaskMapping, DatastoreOptions>, taskKind: TaskKind, handler: (task: Task<TaskKind, TaskMapping[TaskKind]>) => Promise<void>, backOffStrategy: BackoffStrategy, config?: Partial<SimpleProcessorConfig>);
|
|
32
24
|
/**
|
|
33
25
|
* Validates that the task handler timeout is less than the claim stale timeout.
|
|
34
26
|
* Throws an error if the validation fails.
|
|
@@ -4,37 +4,33 @@ exports.SimpleProcessor = void 0;
|
|
|
4
4
|
const node_stream_1 = require("node:stream");
|
|
5
5
|
const promises_1 = require("node:timers/promises");
|
|
6
6
|
const promise_utils_1 = require("../utils/promise-utils");
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
const DEFAULT_CONFIG = {
|
|
8
|
+
maxConcurrency: 1,
|
|
9
|
+
claimIntervalMs: 50,
|
|
10
|
+
claimStaleTimeoutMs: 10_000,
|
|
11
|
+
idleIntervalMs: 5_000,
|
|
12
|
+
taskHandlerTimeoutMs: 5_000,
|
|
13
|
+
taskHandlerMaxRetries: 10,
|
|
14
|
+
processLoopRetryIntervalMs: 20_000,
|
|
15
|
+
};
|
|
13
16
|
class SimpleProcessor extends node_stream_1.EventEmitter {
|
|
14
|
-
taskKind;
|
|
15
17
|
datastore;
|
|
18
|
+
taskKind;
|
|
16
19
|
handler;
|
|
17
|
-
maxConcurrency;
|
|
18
20
|
backOffStrategy;
|
|
19
|
-
|
|
20
|
-
claimStaleTimeoutMs;
|
|
21
|
-
idleIntervalMs;
|
|
22
|
-
taskHandlerTimeoutMs;
|
|
23
|
-
taskHandlerMaxRetries;
|
|
21
|
+
config;
|
|
24
22
|
exitChannels = [];
|
|
25
23
|
stopRequested = false;
|
|
26
|
-
constructor(config) {
|
|
24
|
+
constructor(datastore, taskKind, handler, backOffStrategy, config) {
|
|
27
25
|
super();
|
|
28
|
-
this.datastore =
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
31
|
-
this.backOffStrategy =
|
|
32
|
-
this.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.taskHandlerTimeoutMs = config.taskHandlerTimeoutMs || DEFAULT_TASK_HANDLER_TIMEOUT_MS;
|
|
37
|
-
this.taskHandlerMaxRetries = config.taskHandlerMaxRetries || DEFAULT_TASK_HANDLER_MAX_RETRIES;
|
|
26
|
+
this.datastore = datastore;
|
|
27
|
+
this.taskKind = taskKind;
|
|
28
|
+
this.handler = handler;
|
|
29
|
+
this.backOffStrategy = backOffStrategy;
|
|
30
|
+
this.config = {
|
|
31
|
+
...DEFAULT_CONFIG,
|
|
32
|
+
...config,
|
|
33
|
+
};
|
|
38
34
|
this.validatedHandlerTimeout();
|
|
39
35
|
}
|
|
40
36
|
/**
|
|
@@ -46,8 +42,8 @@ class SimpleProcessor extends node_stream_1.EventEmitter {
|
|
|
46
42
|
* @throws {Error} If the task handler timeout is greater than or equal to the claim stale timeout.
|
|
47
43
|
*/
|
|
48
44
|
validatedHandlerTimeout() {
|
|
49
|
-
if (this.taskHandlerTimeoutMs >= this.claimStaleTimeoutMs) {
|
|
50
|
-
throw new Error(`Task handler timeout (${this.taskHandlerTimeoutMs}ms) must be less than the claim stale timeout (${this.claimStaleTimeoutMs}ms)`);
|
|
45
|
+
if (this.config.taskHandlerTimeoutMs >= this.config.claimStaleTimeoutMs) {
|
|
46
|
+
throw new Error(`Task handler timeout (${this.config.taskHandlerTimeoutMs}ms) must be less than the claim stale timeout (${this.config.claimStaleTimeoutMs}ms)`);
|
|
51
47
|
}
|
|
52
48
|
}
|
|
53
49
|
/**
|
|
@@ -58,7 +54,7 @@ class SimpleProcessor extends node_stream_1.EventEmitter {
|
|
|
58
54
|
if (this.stopRequested || this.exitChannels.length > 0) {
|
|
59
55
|
return;
|
|
60
56
|
}
|
|
61
|
-
for (let i = 0; i < this.maxConcurrency; i++) {
|
|
57
|
+
for (let i = 0; i < this.config.maxConcurrency; i++) {
|
|
62
58
|
const exitChannel = new node_stream_1.EventEmitter();
|
|
63
59
|
this.exitChannels.push(exitChannel);
|
|
64
60
|
this.runProcessLoop(exitChannel);
|
|
@@ -69,7 +65,7 @@ class SimpleProcessor extends node_stream_1.EventEmitter {
|
|
|
69
65
|
* then waits for all process loops to finish before resolving.
|
|
70
66
|
*/
|
|
71
67
|
async stop() {
|
|
72
|
-
const exitPromises = this.exitChannels.map((channel) => new Promise((resolve) => channel.once('processloop
|
|
68
|
+
const exitPromises = this.exitChannels.map((channel) => new Promise((resolve) => channel.once('processloop:exit', resolve)));
|
|
73
69
|
this.stopRequested = true;
|
|
74
70
|
await Promise.all(exitPromises);
|
|
75
71
|
}
|
|
@@ -83,21 +79,22 @@ class SimpleProcessor extends node_stream_1.EventEmitter {
|
|
|
83
79
|
try {
|
|
84
80
|
const task = await this.datastore.claim({
|
|
85
81
|
kind: this.taskKind,
|
|
86
|
-
claimStaleTimeoutMs: this.claimStaleTimeoutMs,
|
|
82
|
+
claimStaleTimeoutMs: this.config.claimStaleTimeoutMs,
|
|
87
83
|
});
|
|
88
84
|
// If no tasks are available, wait before trying again
|
|
89
85
|
if (!task) {
|
|
90
|
-
await (0, promises_1.setTimeout)(this.idleIntervalMs);
|
|
86
|
+
await (0, promises_1.setTimeout)(this.config.idleIntervalMs);
|
|
91
87
|
continue;
|
|
92
88
|
}
|
|
93
89
|
this.emit('task:claimed', { task, timestamp: new Date() });
|
|
94
90
|
// Process the task using the handler
|
|
95
91
|
await this.handleTask(task);
|
|
96
92
|
// Wait a bit before claiming the next task
|
|
97
|
-
await (0, promises_1.setTimeout)(this.claimIntervalMs);
|
|
93
|
+
await (0, promises_1.setTimeout)(this.config.claimIntervalMs);
|
|
98
94
|
}
|
|
99
95
|
catch (error) {
|
|
100
96
|
this.emit('processloop:error', { error: error, timestamp: new Date() });
|
|
97
|
+
await (0, promises_1.setTimeout)(this.config.processLoopRetryIntervalMs);
|
|
101
98
|
}
|
|
102
99
|
}
|
|
103
100
|
exitChannel.emit('processloop:exit');
|
|
@@ -114,7 +111,7 @@ class SimpleProcessor extends node_stream_1.EventEmitter {
|
|
|
114
111
|
*/
|
|
115
112
|
async handleTask(task) {
|
|
116
113
|
try {
|
|
117
|
-
await (0, promise_utils_1.promiseWithTimeout)(this.handler(task), this.taskHandlerTimeoutMs);
|
|
114
|
+
await (0, promise_utils_1.promiseWithTimeout)(this.handler(task), this.config.taskHandlerTimeoutMs);
|
|
118
115
|
}
|
|
119
116
|
catch (error) {
|
|
120
117
|
await this.handleTaskError(task, error);
|
|
@@ -136,7 +133,7 @@ class SimpleProcessor extends node_stream_1.EventEmitter {
|
|
|
136
133
|
}
|
|
137
134
|
}
|
|
138
135
|
async handleTaskError(task, error) {
|
|
139
|
-
if (task.retryCount >= this.taskHandlerMaxRetries) {
|
|
136
|
+
if (task.retryCount >= this.config.taskHandlerMaxRetries) {
|
|
140
137
|
// Mark the task as failed
|
|
141
138
|
await this.datastore.fail(task.id);
|
|
142
139
|
this.emit('task:failed', {
|
|
@@ -147,9 +144,9 @@ class SimpleProcessor extends node_stream_1.EventEmitter {
|
|
|
147
144
|
return;
|
|
148
145
|
}
|
|
149
146
|
const delay = this.backOffStrategy({ retryAttempt: task.retryCount });
|
|
150
|
-
const
|
|
151
|
-
await this.datastore.
|
|
152
|
-
this.emit('task:
|
|
147
|
+
const retryAt = new Date(Date.now() + delay);
|
|
148
|
+
await this.datastore.retry(task.id, retryAt);
|
|
149
|
+
this.emit('task:retry:requested', {
|
|
153
150
|
task,
|
|
154
151
|
error,
|
|
155
152
|
timestamp: new Date(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-processor.js","sourceRoot":"","sources":["../../src/processors/simple-processor.ts"],"names":[],"mappings":";;;AAAA,6CAA2C;AAC3C,mDAAkD;AAKlD,0DAA4D;AAG5D,MAAM,
|
|
1
|
+
{"version":3,"file":"simple-processor.js","sourceRoot":"","sources":["../../src/processors/simple-processor.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neofinancial/chrono",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Core package for Chrono task scheduling system",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
|
+
"homepage": "https://github.com/neofinancial/chrono",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/neofinancial/chrono.git"
|
|
13
|
+
},
|
|
9
14
|
"main": "build/index.js",
|
|
10
15
|
"types": "build/index.d.ts",
|
|
11
16
|
"files": [
|
|
12
|
-
"build/**"
|
|
17
|
+
"build/**",
|
|
18
|
+
"README.md"
|
|
13
19
|
],
|
|
14
20
|
"keywords": [],
|
|
15
21
|
"author": "Neo Financial Engineering <engineering@neofinancial.com>",
|
package/build/scheduler.d.ts
DELETED
package/build/scheduler.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Scheduler = void 0;
|
|
4
|
-
class Scheduler {
|
|
5
|
-
#tasks = [];
|
|
6
|
-
constructor() {
|
|
7
|
-
this.#tasks = [];
|
|
8
|
-
}
|
|
9
|
-
async schedule(task) {
|
|
10
|
-
this.#tasks.push(task);
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
async run() {
|
|
14
|
-
for (const task of this.#tasks) {
|
|
15
|
-
task.run();
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
exports.Scheduler = Scheduler;
|
|
21
|
-
//# sourceMappingURL=scheduler.js.map
|
package/build/scheduler.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":";;;AAIA,MAAa,SAAS;IACpB,MAAM,GAAc,EAAE,CAAC;IAEvB;QACE,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAa;QACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEvB,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,GAAG;QACd,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AApBD,8BAoBC"}
|
package/build/task.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export declare const TaskStatus: {
|
|
2
|
-
readonly PENDING: "PENDING";
|
|
3
|
-
readonly CLAIMED: "CLAIMED";
|
|
4
|
-
readonly COMPLETED: "COMPLETED";
|
|
5
|
-
readonly FAILED: "FAILED";
|
|
6
|
-
};
|
|
7
|
-
export type TaskStatus = (typeof TaskStatus)[keyof typeof TaskStatus];
|
|
8
|
-
export type Task<TaskKind, TaskData> = {
|
|
9
|
-
/** A unique identifier for the task */
|
|
10
|
-
id: string;
|
|
11
|
-
/** A human-readable name or type for the task */
|
|
12
|
-
kind: TaskKind;
|
|
13
|
-
/** The current status of the task */
|
|
14
|
-
status: TaskStatus;
|
|
15
|
-
/** The payload or data associated with the task */
|
|
16
|
-
data: TaskData;
|
|
17
|
-
/** The priority level of the task (lower numbers can indicate higher priority) */
|
|
18
|
-
priority?: number;
|
|
19
|
-
/** A key used for idempotency to prevent duplicate processing */
|
|
20
|
-
idempotencyKey?: string;
|
|
21
|
-
/** The original scheduled date when the task was first intended to run */
|
|
22
|
-
originalScheduleDate: Date;
|
|
23
|
-
/** The current scheduled execution date, which may change if rescheduled */
|
|
24
|
-
scheduledAt: Date;
|
|
25
|
-
/** The date the task is mark 'claimed */
|
|
26
|
-
claimedAt?: Date;
|
|
27
|
-
/** The date the task is mark 'completed' */
|
|
28
|
-
completedAt?: Date;
|
|
29
|
-
/** The date when the task was last executed (if any) */
|
|
30
|
-
lastExecutedAt?: Date;
|
|
31
|
-
/** A counter to track the number of times the task has been retried */
|
|
32
|
-
retryCount: number;
|
|
33
|
-
};
|
package/build/task.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TaskStatus = void 0;
|
|
4
|
-
exports.TaskStatus = {
|
|
5
|
-
PENDING: "PENDING",
|
|
6
|
-
CLAIMED: "CLAIMED",
|
|
7
|
-
COMPLETED: "COMPLETED",
|
|
8
|
-
FAILED: "FAILED",
|
|
9
|
-
};
|
|
10
|
-
//# sourceMappingURL=task.js.map
|
package/build/task.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG;IACxB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;CACR,CAAC"}
|