@strav/queue 0.3.19 → 0.3.21
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/package.json +3 -3
- package/src/scheduler/schedule.ts +30 -0
- package/src/scheduler/scheduler.ts +24 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strav/queue",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Background job processing and task scheduling for the Strav framework",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"./providers/*": "./src/providers/*.ts"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@strav/kernel": "0.3.
|
|
32
|
-
"@strav/database": "0.3.
|
|
31
|
+
"@strav/kernel": "0.3.21",
|
|
32
|
+
"@strav/database": "0.3.21"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"test": "bun test tests/",
|
|
@@ -38,6 +38,7 @@ export class Schedule {
|
|
|
38
38
|
|
|
39
39
|
private _cron: CronExpression | null = null
|
|
40
40
|
private _noOverlap = false
|
|
41
|
+
private _runImmediately = false
|
|
41
42
|
|
|
42
43
|
private _sporadicMin: number | null = null
|
|
43
44
|
private _sporadicMax: number | null = null
|
|
@@ -179,6 +180,22 @@ export class Schedule {
|
|
|
179
180
|
return this
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Execute this task immediately upon registration, then follow the configured schedule.
|
|
185
|
+
* Useful for bootstrap tasks, cache warming, or ensuring tasks run on deployment.
|
|
186
|
+
*/
|
|
187
|
+
runImmediately(): this {
|
|
188
|
+
this._runImmediately = true
|
|
189
|
+
|
|
190
|
+
// Execute the handler immediately
|
|
191
|
+
this.executeHandler().catch(error => {
|
|
192
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
193
|
+
console.error(`[scheduler] Immediate execution of "${this.name}" failed: ${message}`)
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
return this
|
|
197
|
+
}
|
|
198
|
+
|
|
182
199
|
// ── Internal ──────────────────────────────────────────────────────────────
|
|
183
200
|
|
|
184
201
|
/** Check if this task is due at the given Date (evaluated in UTC). */
|
|
@@ -201,6 +218,11 @@ export class Schedule {
|
|
|
201
218
|
return this._noOverlap
|
|
202
219
|
}
|
|
203
220
|
|
|
221
|
+
/** Whether this task should run immediately upon registration. */
|
|
222
|
+
get shouldRunImmediately(): boolean {
|
|
223
|
+
return this._runImmediately
|
|
224
|
+
}
|
|
225
|
+
|
|
204
226
|
/** The parsed cron expression (for testing/debugging). */
|
|
205
227
|
get expression(): CronExpression | null {
|
|
206
228
|
return this._cron
|
|
@@ -211,6 +233,14 @@ export class Schedule {
|
|
|
211
233
|
return this._nextRunAt
|
|
212
234
|
}
|
|
213
235
|
|
|
236
|
+
/** Execute the task handler, handling both sync and async cases. */
|
|
237
|
+
private async executeHandler(): Promise<void> {
|
|
238
|
+
const result = this.handler()
|
|
239
|
+
if (result instanceof Promise) {
|
|
240
|
+
await result
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
214
244
|
/** Compute the next random run time from a reference point. */
|
|
215
245
|
private computeNextRun(from: Date): Date {
|
|
216
246
|
const ms = unitToMs(this._sporadicUnit!)
|
|
@@ -40,6 +40,30 @@ export default class Scheduler {
|
|
|
40
40
|
return Scheduler._tasks.filter(t => t.isDue(date))
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Manually execute a task by name immediately.
|
|
45
|
+
*
|
|
46
|
+
* @param name The name of the task to execute
|
|
47
|
+
* @returns Promise that resolves when the task completes
|
|
48
|
+
* @throws Error if task is not found
|
|
49
|
+
*/
|
|
50
|
+
static async runNow(name: string): Promise<void> {
|
|
51
|
+
const task = Scheduler._tasks.find(t => t.name === name)
|
|
52
|
+
if (!task) {
|
|
53
|
+
throw new Error(`Task "${name}" not found. Available tasks: ${Scheduler._tasks.map(t => t.name).join(', ')}`)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const result = task.handler()
|
|
58
|
+
if (result instanceof Promise) {
|
|
59
|
+
await result
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
63
|
+
throw new Error(`Manual execution of task "${name}" failed: ${message}`)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
43
67
|
/** Clear all registered tasks. For testing. */
|
|
44
68
|
static reset(): void {
|
|
45
69
|
Scheduler._tasks = []
|