@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 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.failed', { error, timestamp: new Date() });
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);
@@ -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;YAExE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAClD,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,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;AAzED,wBAyEC"}
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"}
@@ -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
- unclaim<TaskKind extends keyof TaskMapping>(taskId: string, nextScheduledAt: Date): Promise<Task<TaskKind, TaskMapping[TaskKind]>>;
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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAgF;AAAvE,gGAAA,MAAM,OAAA;AACf,yCAAsL;AAA7K,uGAAA,UAAU,OAAA"}
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":";;AA2BA,0CAmBC;AA5CD,0DAA0F;AAE1F,yDAAqD;AAuBrD,SAAgB,eAAe,CAI7B,KAAoE;IACpE,MAAM,eAAe,GAAG,IAAA,yCAAsB,EAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC7E,2BAA2B;IAC3B,OAAO,IAAI,kCAAe,CAA0C;QAClE,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,cAAc,EAAE,KAAK,CAAC,aAAa,EAAE,cAAc;QACnD,eAAe;QACf,eAAe,EAAE,KAAK,CAAC,aAAa,EAAE,eAAe;QACrD,cAAc,EAAE,KAAK,CAAC,aAAa,EAAE,cAAc;QACnD,oBAAoB,EAAE,KAAK,CAAC,aAAa,EAAE,oBAAoB;QAC/D,mBAAmB,EAAE,KAAK,CAAC,aAAa,EAAE,mBAAmB;QAC7D,qBAAqB,EAAE,KAAK,CAAC,aAAa,EAAE,qBAAqB;KAClE,CAAC,CAAC;AACL,CAAC"}
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:unclaimed': [{
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<TaskKind extends keyof TaskMapping, TaskMapping extends TaskMappingBase, DatastoreOptions> = {
7
- datastore: Datastore<TaskMapping, DatastoreOptions>;
8
- kind: TaskKind;
9
- handler: (task: Task<TaskKind, TaskMapping[TaskKind]>) => Promise<void>;
10
- maxConcurrency?: number;
11
- backoffStrategy: BackoffStrategy;
12
- claimIntervalMs?: number;
13
- claimStaleTimeoutMs?: number;
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
- readonly taskKind: TaskKind;
20
- readonly datastore: Datastore<TaskMapping, DatastoreOptions>;
21
- readonly handler: (task: Task<TaskKind, TaskMapping[TaskKind]>) => Promise<void>;
22
- private maxConcurrency;
16
+ private datastore;
17
+ private taskKind;
18
+ private handler;
23
19
  private backOffStrategy;
24
- readonly claimIntervalMs: number;
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(config: SimpleProcessorConfig<TaskKind, TaskMapping, DatastoreOptions>);
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 DEFAULT_MAX_CONCURRENCY = 1;
8
- const DEFAULT_CLAIM_INTERVAL_MS = 50;
9
- const DEFAULT_CLAIM_STALE_TIMEOUT_MS = 10_000;
10
- const DEFAULT_IDLE_INTERVAL_MS = 5_000;
11
- const DEFAULT_TASK_HANDLER_TIMEOUT_MS = 5_000;
12
- const DEFAULT_TASK_HANDLER_MAX_RETRIES = 10;
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
- claimIntervalMs;
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 = config.datastore;
29
- this.handler = config.handler;
30
- this.taskKind = config.kind;
31
- this.backOffStrategy = config.backoffStrategy;
32
- this.maxConcurrency = config.maxConcurrency || DEFAULT_MAX_CONCURRENCY;
33
- this.claimIntervalMs = config.claimIntervalMs || DEFAULT_CLAIM_INTERVAL_MS;
34
- this.claimStaleTimeoutMs = config.claimStaleTimeoutMs || DEFAULT_CLAIM_STALE_TIMEOUT_MS;
35
- this.idleIntervalMs = config.idleIntervalMs || DEFAULT_IDLE_INTERVAL_MS;
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.exit', resolve)));
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 nextScheduledAt = new Date(Date.now() + delay);
151
- await this.datastore.unclaim(task.id, nextScheduledAt);
152
- this.emit('task:unclaimed', {
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":"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"}
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.0",
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>",
@@ -1,9 +0,0 @@
1
- export interface Task<T> {
2
- run(): Promise<T>;
3
- }
4
- export declare class Scheduler<T> {
5
- #private;
6
- constructor();
7
- schedule(task: Task<T>): Promise<boolean>;
8
- run(): Promise<boolean>;
9
- }
@@ -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
@@ -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"}