@fluojs/cron 1.0.3 → 1.1.0
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.ko.md +8 -2
- package/README.md +8 -2
- package/dist/distributed-lock-manager.d.ts +6 -1
- package/dist/distributed-lock-manager.d.ts.map +1 -1
- package/dist/distributed-lock-manager.js +43 -3
- package/dist/service.d.ts +8 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +65 -11
- package/dist/status.d.ts +1 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +17 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -5
package/README.ko.md
CHANGED
|
@@ -41,6 +41,8 @@ npm install @fluojs/cron croner
|
|
|
41
41
|
애플리케이션 모듈의 스케줄링 등록은 `CronModule.forRoot(...)`로 구성합니다.
|
|
42
42
|
Cron 표현식은 다섯 필드(`minute hour day month weekday`) 또는 여섯 필드(`second minute hour day month weekday`)를 사용할 수 있습니다. 내장 `CronExpression` preset은 sub-minute 정밀도가 필요할 때 여섯 필드 표현식을 사용합니다. Cron task는 application bootstrap 이후에만 시작되고, 이미 시작된 registry에 동적으로 등록한 cron task는 등록 시점에 시작되며, fluo는 `timezone`과 no-overlap 보호를 scheduler에 전달해 같은 task instance가 자기 자신과 겹쳐 실행되지 않게 합니다.
|
|
43
43
|
|
|
44
|
+
Scheduling decorator는 public instance method에만 적용됩니다. NestJS에서 사용하던 private scheduled method, static helper, legacy decorator metadata 가정 뒤에 숨은 method name을 그대로 옮기지 마세요. 공개 provider/controller method를 노출하고 private 구현 세부사항은 그 method 뒤에 두세요.
|
|
45
|
+
|
|
44
46
|
```typescript
|
|
45
47
|
import { Module } from '@fluojs/core';
|
|
46
48
|
import { CronModule, Cron, CronExpression, Interval, Timeout } from '@fluojs/cron';
|
|
@@ -137,15 +139,19 @@ class TaskManager {
|
|
|
137
139
|
});
|
|
138
140
|
}
|
|
139
141
|
|
|
142
|
+
speedUpPolling() {
|
|
143
|
+
this.registry.updateIntervalMs('inventory.poll', 5_000);
|
|
144
|
+
}
|
|
145
|
+
|
|
140
146
|
stopTask() {
|
|
141
147
|
this.registry.remove('dynamic-job');
|
|
142
148
|
}
|
|
143
149
|
}
|
|
144
150
|
```
|
|
145
151
|
|
|
146
|
-
Registry는 `addCron`, `addInterval`, `addTimeout`, `remove`, `enable`, `disable`, `get`, `getAll`, `updateCronExpression
|
|
152
|
+
Registry는 `addCron`, `addInterval`, `addTimeout`, `remove`, `enable`, `disable`, `get`, `getAll`, `updateCronExpression`, `updateIntervalMs`를 제공합니다. 첫 번째 `name` 인자는 기본 registry key이며, `options.name`을 전달하면 dynamic task의 실제 registry key, scheduler metadata name, 기본 distributed lock key가 이를 사용해 decorator naming semantics와 일치합니다. `get`과 `getAll`은 live `CronJob` handle이 아니라 read-only `SchedulingTaskDescriptor` 값을 반환합니다. Timeout task는 한 번 실행된 뒤 비활성화되지만 registry에는 남아 있어 의도적으로 다시 활성화할 수 있습니다.
|
|
147
153
|
|
|
148
|
-
Dynamic cron 등록은 scheduler startup과 원자적으로 처리됩니다. Scheduler가 새 cron job을 거부하면 registry는 half-registered task를 남기지 않습니다. 실행 중인 cron expression update도 rollback-safe합니다. Rescheduling이 실패하면 이전 expression
|
|
154
|
+
Dynamic cron 등록은 scheduler startup과 원자적으로 처리됩니다. Scheduler가 새 cron job을 거부하면 registry는 half-registered task를 남기지 않습니다. 실행 중인 cron expression 또는 interval cadence update도 rollback-safe합니다. Rescheduling이 실패하면 이전 expression 또는 interval milliseconds와 scheduled handle이 그대로 유지됩니다. Cron task는 scheduler-level no-overlap protection과 fluo의 in-process running guard를 함께 사용하므로 같은 task instance가 overlapping tick으로 실행되지 않습니다.
|
|
149
155
|
|
|
150
156
|
### 제한된 종료
|
|
151
157
|
|
package/README.md
CHANGED
|
@@ -41,6 +41,8 @@ Register the `CronModule` and use decorators to schedule your methods.
|
|
|
41
41
|
Use `CronModule.forRoot(...)` to register scheduling for an application module.
|
|
42
42
|
Cron expressions may use either five fields (`minute hour day month weekday`) or six fields (`second minute hour day month weekday`). The built-in `CronExpression` presets use six-field expressions when sub-minute precision is needed. Cron tasks start only after application bootstrap, dynamically registered cron tasks start when added to a started registry, and fluo forwards `timezone` plus no-overlap protection to the scheduler so one task instance does not overlap itself.
|
|
43
43
|
|
|
44
|
+
Scheduling decorators apply to public instance methods only. Do not migrate NestJS private scheduled methods, static helpers, or method names that are hidden behind legacy decorator metadata assumptions as-is; expose a public provider/controller method and keep any private implementation details behind that method.
|
|
45
|
+
|
|
44
46
|
```typescript
|
|
45
47
|
import { Module } from '@fluojs/core';
|
|
46
48
|
import { CronModule, Cron, CronExpression, Interval, Timeout } from '@fluojs/cron';
|
|
@@ -137,15 +139,19 @@ class TaskManager {
|
|
|
137
139
|
});
|
|
138
140
|
}
|
|
139
141
|
|
|
142
|
+
speedUpPolling() {
|
|
143
|
+
this.registry.updateIntervalMs('inventory.poll', 5_000);
|
|
144
|
+
}
|
|
145
|
+
|
|
140
146
|
stopTask() {
|
|
141
147
|
this.registry.remove('dynamic-job');
|
|
142
148
|
}
|
|
143
149
|
}
|
|
144
150
|
```
|
|
145
151
|
|
|
146
|
-
The registry exposes `addCron`, `addInterval`, `addTimeout`, `remove`, `enable`, `disable`, `get`, `getAll`, and `
|
|
152
|
+
The registry exposes `addCron`, `addInterval`, `addTimeout`, `remove`, `enable`, `disable`, `get`, `getAll`, `updateCronExpression`, and `updateIntervalMs`. The first `name` argument is the default registry key; passing `options.name` overrides the actual registry key, scheduler metadata name, and default distributed lock key for dynamic tasks so dynamic registration matches decorator naming semantics. `get` and `getAll` return read-only `SchedulingTaskDescriptor` values, not live `CronJob` handles. Timeout tasks run once, then disable themselves while remaining in the registry so they can be re-enabled deliberately.
|
|
147
153
|
|
|
148
|
-
Dynamic cron registration is atomic with scheduler startup: if the scheduler rejects a new cron job, the registry does not retain a half-registered task. Updating a running cron expression is also rollback-safe. If rescheduling fails, the previous expression and scheduled
|
|
154
|
+
Dynamic cron registration is atomic with scheduler startup: if the scheduler rejects a new cron job, the registry does not retain a half-registered task. Updating a running cron expression or interval cadence is also rollback-safe. If rescheduling fails, the previous expression or interval milliseconds and scheduled handle remain active. Cron tasks use both scheduler-level no-overlap protection and fluo's in-process running guard, so the same task instance will not run overlapping ticks.
|
|
149
155
|
|
|
150
156
|
### Bounded Shutdown
|
|
151
157
|
|
|
@@ -17,19 +17,21 @@ export declare class CronDistributedLockManager {
|
|
|
17
17
|
private readonly runtimeContainer;
|
|
18
18
|
private readonly logger;
|
|
19
19
|
private readonly ownedLockKeys;
|
|
20
|
+
private lockIoError;
|
|
20
21
|
private redisClient;
|
|
21
22
|
private lockOwnershipLosses;
|
|
22
23
|
private lockRenewalFailures;
|
|
23
24
|
constructor(options: NormalizedCronModuleOptions, runtimeContainer: Container, logger: ApplicationLogger);
|
|
24
25
|
get resolvedClient(): RedisLockClient | undefined;
|
|
25
26
|
get ownedLocks(): number;
|
|
27
|
+
get lockIoAvailable(): boolean;
|
|
26
28
|
get ownershipLosses(): number;
|
|
27
29
|
get renewalFailures(): number;
|
|
28
30
|
resolveClient(): Promise<void>;
|
|
29
31
|
reset(): void;
|
|
30
32
|
tryAcquireLock(descriptor: CronTaskDescriptor): Promise<boolean>;
|
|
31
33
|
startLockRenewalMonitor(descriptor: CronTaskDescriptor): LockRenewalMonitor;
|
|
32
|
-
releaseLock(descriptor: CronTaskDescriptor): Promise<
|
|
34
|
+
releaseLock(descriptor: CronTaskDescriptor): Promise<boolean>;
|
|
33
35
|
releaseOwnedLocks(excludedLockKeys?: ReadonlySet<string>): Promise<void>;
|
|
34
36
|
private createLockRenewalState;
|
|
35
37
|
private queueDueLockRenewalAttempts;
|
|
@@ -37,5 +39,8 @@ export declare class CronDistributedLockManager {
|
|
|
37
39
|
private toLockPostRunError;
|
|
38
40
|
private renewLock;
|
|
39
41
|
private releaseLockKey;
|
|
42
|
+
private verifyLockIoAvailability;
|
|
43
|
+
private markLockIoAvailable;
|
|
44
|
+
private markLockIoUnavailable;
|
|
40
45
|
}
|
|
41
46
|
//# sourceMappingURL=distributed-lock-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distributed-lock-manager.d.ts","sourceRoot":"","sources":["../src/distributed-lock-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAElF,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC7G;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,eAAe,IAAI,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAC9C,IAAI,IAAI,IAAI,CAAC;CACd;AAoDD,yFAAyF;AACzF,qBAAa,0BAA0B;
|
|
1
|
+
{"version":3,"file":"distributed-lock-manager.d.ts","sourceRoot":"","sources":["../src/distributed-lock-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAElF,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC7G;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,eAAe,IAAI,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAC9C,IAAI,IAAI,IAAI,CAAC;CACd;AAoDD,yFAAyF;AACzF,qBAAa,0BAA0B;IAQnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM;IATzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,mBAAmB,CAAK;gBAGb,OAAO,EAAE,2BAA2B,EACpC,gBAAgB,EAAE,SAAS,EAC3B,MAAM,EAAE,iBAAiB;IAG5C,IAAI,cAAc,IAAI,eAAe,GAAG,SAAS,CAEhD;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,eAAe,IAAI,OAAO,CAM7B;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAEK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBpC,KAAK,IAAI,IAAI;IAKP,cAAc,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAkCtE,uBAAuB,CAAC,UAAU,EAAE,kBAAkB,GAAG,kBAAkB;IA8BrE,WAAW,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7D,iBAAiB,CAAC,gBAAgB,GAAE,WAAW,CAAC,MAAM,CAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBzF,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,2BAA2B;YAcrB,qBAAqB;IAqBnC,OAAO,CAAC,kBAAkB;YAYZ,SAAS;YA2CT,cAAc;YAsCd,wBAAwB;IAmBtC,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,qBAAqB;CAG9B"}
|
|
@@ -30,6 +30,7 @@ async function resolveRedisPeerModule() {
|
|
|
30
30
|
/** Coordinates Redis lock acquisition, renewal, and release for scheduled cron tasks. */
|
|
31
31
|
export class CronDistributedLockManager {
|
|
32
32
|
ownedLockKeys = new Set();
|
|
33
|
+
lockIoError;
|
|
33
34
|
redisClient;
|
|
34
35
|
lockOwnershipLosses = 0;
|
|
35
36
|
lockRenewalFailures = 0;
|
|
@@ -44,6 +45,12 @@ export class CronDistributedLockManager {
|
|
|
44
45
|
get ownedLocks() {
|
|
45
46
|
return this.ownedLockKeys.size;
|
|
46
47
|
}
|
|
48
|
+
get lockIoAvailable() {
|
|
49
|
+
if (!this.options.distributed.enabled) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return this.redisClient !== undefined && this.lockIoError === undefined;
|
|
53
|
+
}
|
|
47
54
|
get ownershipLosses() {
|
|
48
55
|
return this.lockOwnershipLosses;
|
|
49
56
|
}
|
|
@@ -66,8 +73,10 @@ export class CronDistributedLockManager {
|
|
|
66
73
|
throw new Error('Cron distributed mode requires the configured Redis client to implement set/eval lock operations.');
|
|
67
74
|
}
|
|
68
75
|
this.redisClient = redisClient;
|
|
76
|
+
await this.verifyLockIoAvailability();
|
|
69
77
|
}
|
|
70
78
|
reset() {
|
|
79
|
+
this.lockIoError = undefined;
|
|
71
80
|
this.redisClient = undefined;
|
|
72
81
|
}
|
|
73
82
|
async tryAcquireLock(descriptor) {
|
|
@@ -77,11 +86,13 @@ export class CronDistributedLockManager {
|
|
|
77
86
|
}
|
|
78
87
|
try {
|
|
79
88
|
const result = await redis.set(descriptor.lockKey, this.options.distributed.ownerId, 'PX', descriptor.lockTtlMs, 'NX');
|
|
89
|
+
this.markLockIoAvailable();
|
|
80
90
|
if (result === 'OK') {
|
|
81
91
|
this.ownedLockKeys.add(descriptor.lockKey);
|
|
82
92
|
}
|
|
83
93
|
return result === 'OK';
|
|
84
94
|
} catch (error) {
|
|
95
|
+
this.markLockIoUnavailable(error);
|
|
85
96
|
this.logger.error(`Failed to acquire distributed cron lock for ${descriptor.taskName}.`, error, 'CronLifecycleService');
|
|
86
97
|
return false;
|
|
87
98
|
}
|
|
@@ -113,7 +124,7 @@ export class CronDistributedLockManager {
|
|
|
113
124
|
};
|
|
114
125
|
}
|
|
115
126
|
async releaseLock(descriptor) {
|
|
116
|
-
await this.releaseLockKey(descriptor.lockKey, descriptor.taskName);
|
|
127
|
+
return await this.releaseLockKey(descriptor.lockKey, descriptor.taskName);
|
|
117
128
|
}
|
|
118
129
|
async releaseOwnedLocks(excludedLockKeys = new Set()) {
|
|
119
130
|
if (!this.redisClient || this.ownedLockKeys.size === 0) {
|
|
@@ -176,12 +187,15 @@ export class CronDistributedLockManager {
|
|
|
176
187
|
try {
|
|
177
188
|
const result = await redis.eval(RENEW_LOCK_SCRIPT, 1, descriptor.lockKey, this.options.distributed.ownerId, String(descriptor.lockTtlMs));
|
|
178
189
|
if (typeof result === 'number' && result <= 0) {
|
|
190
|
+
this.markLockIoAvailable();
|
|
179
191
|
this.logger.warn(`Distributed cron lock ownership was lost for ${descriptor.taskName}.`, 'CronLifecycleService');
|
|
180
192
|
return 'ownership-lost';
|
|
181
193
|
}
|
|
194
|
+
this.markLockIoAvailable();
|
|
182
195
|
this.logger.log(`Renewed distributed cron lock for ${descriptor.taskName}.`, 'CronLifecycleService');
|
|
183
196
|
return 'renewed';
|
|
184
197
|
} catch (error) {
|
|
198
|
+
this.markLockIoUnavailable(error);
|
|
185
199
|
this.logger.error(`Failed to renew distributed cron lock for ${descriptor.taskName}.`, error, 'CronLifecycleService');
|
|
186
200
|
return 'renewal-failed';
|
|
187
201
|
}
|
|
@@ -189,21 +203,47 @@ export class CronDistributedLockManager {
|
|
|
189
203
|
async releaseLockKey(lockKey, taskName) {
|
|
190
204
|
const redis = this.redisClient;
|
|
191
205
|
if (!redis) {
|
|
192
|
-
return;
|
|
206
|
+
return true;
|
|
193
207
|
}
|
|
194
208
|
try {
|
|
195
209
|
const result = await redis.eval(RELEASE_LOCK_SCRIPT, 1, lockKey, this.options.distributed.ownerId);
|
|
196
210
|
if (typeof result === 'number' && result <= 0) {
|
|
211
|
+
this.markLockIoAvailable();
|
|
197
212
|
this.logger.warn(`Distributed cron lock for ${taskName} was already released or owned by another node.`, 'CronLifecycleService');
|
|
198
213
|
this.ownedLockKeys.delete(lockKey);
|
|
199
|
-
return;
|
|
214
|
+
return true;
|
|
200
215
|
}
|
|
216
|
+
this.markLockIoAvailable();
|
|
201
217
|
this.logger.log(`Released distributed cron lock for ${taskName}.`, 'CronLifecycleService');
|
|
202
218
|
this.ownedLockKeys.delete(lockKey);
|
|
219
|
+
return true;
|
|
203
220
|
} catch (error) {
|
|
221
|
+
this.markLockIoUnavailable(error);
|
|
204
222
|
this.logger.error(`Failed to release distributed cron lock for ${taskName}.`, error, 'CronLifecycleService');
|
|
223
|
+
return false;
|
|
205
224
|
}
|
|
206
225
|
}
|
|
226
|
+
async verifyLockIoAvailability() {
|
|
227
|
+
const redis = this.redisClient;
|
|
228
|
+
if (!redis) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const probeKey = `${this.options.distributed.keyPrefix}:__probe:${this.options.distributed.ownerId}`;
|
|
232
|
+
try {
|
|
233
|
+
await redis.set(probeKey, this.options.distributed.ownerId, 'PX', 1_000, 'NX');
|
|
234
|
+
await redis.eval(RELEASE_LOCK_SCRIPT, 1, probeKey, this.options.distributed.ownerId);
|
|
235
|
+
this.markLockIoAvailable();
|
|
236
|
+
} catch (error) {
|
|
237
|
+
this.markLockIoUnavailable(error);
|
|
238
|
+
throw new Error('Cron distributed mode requires Redis lock I/O to be available.');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
markLockIoAvailable() {
|
|
242
|
+
this.lockIoError = undefined;
|
|
243
|
+
}
|
|
244
|
+
markLockIoUnavailable(error) {
|
|
245
|
+
this.lockIoError = error instanceof Error ? error : new Error('Redis lock I/O failed.');
|
|
246
|
+
}
|
|
207
247
|
}
|
|
208
248
|
function hasRedisLockClient(value) {
|
|
209
249
|
if (typeof value !== 'object' || value === null) {
|
package/dist/service.d.ts
CHANGED
|
@@ -90,12 +90,20 @@ export declare class CronLifecycleService implements SchedulingRegistry, OnAppli
|
|
|
90
90
|
* @param expression New cron expression to validate and schedule.
|
|
91
91
|
*/
|
|
92
92
|
updateCronExpression(name: string, expression: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Replaces the millisecond cadence of one existing interval task.
|
|
95
|
+
*
|
|
96
|
+
* @param name Name of the interval task to update.
|
|
97
|
+
* @param ms New positive interval in milliseconds.
|
|
98
|
+
*/
|
|
99
|
+
updateIntervalMs(name: string, ms: number): void;
|
|
93
100
|
onApplicationBootstrap(): Promise<void>;
|
|
94
101
|
onApplicationShutdown(): Promise<void>;
|
|
95
102
|
onModuleDestroy(): Promise<void>;
|
|
96
103
|
createPlatformStatusSnapshot(): import("./status.js").CronPlatformStatusSnapshot;
|
|
97
104
|
private toSchedulingTaskDescriptor;
|
|
98
105
|
private shutdown;
|
|
106
|
+
private retryReleasedDistributedLocksAfterShutdown;
|
|
99
107
|
private startLifecycle;
|
|
100
108
|
private validateDistributedLockConfiguration;
|
|
101
109
|
private handleStartupFailure;
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/dist/service.js
CHANGED
|
@@ -5,8 +5,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
5
5
|
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
6
|
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
7
|
import { Inject } from '@fluojs/core';
|
|
8
|
-
import { Cron as CronValidator } from 'croner';
|
|
9
8
|
import { APPLICATION_LOGGER, COMPILED_MODULES, RUNTIME_CONTAINER } from '@fluojs/runtime/internal';
|
|
9
|
+
import { Cron as CronValidator } from 'croner';
|
|
10
10
|
import { CronDistributedLockManager } from './distributed-lock-manager.js';
|
|
11
11
|
import { createCronPlatformStatusSnapshot } from './status.js';
|
|
12
12
|
import { createLockKey, discoverCronTaskDescriptors } from './task-discovery.js';
|
|
@@ -22,6 +22,14 @@ function assertValidTaskName(name) {
|
|
|
22
22
|
throw new Error('Scheduling task name must be a non-empty string.');
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
function resolveDynamicTaskName(name, optionName) {
|
|
26
|
+
assertValidTaskName(name);
|
|
27
|
+
if (optionName !== undefined) {
|
|
28
|
+
assertValidTaskName(optionName);
|
|
29
|
+
return optionName;
|
|
30
|
+
}
|
|
31
|
+
return name;
|
|
32
|
+
}
|
|
25
33
|
function assertValidMs(ms, context) {
|
|
26
34
|
if (!Number.isFinite(ms) || !Number.isInteger(ms) || ms <= 0) {
|
|
27
35
|
throw new Error(`${context}: ms must be a positive integer.`);
|
|
@@ -85,8 +93,8 @@ class CronLifecycleService {
|
|
|
85
93
|
* @param options Optional hooks, distributed lock overrides, and timezone.
|
|
86
94
|
*/
|
|
87
95
|
addCron(name, expression, callback, options = {}) {
|
|
88
|
-
assertValidTaskName(name);
|
|
89
96
|
assertValidCronExpression(expression);
|
|
97
|
+
const taskName = resolveDynamicTaskName(name, options.name);
|
|
90
98
|
this.registerTask({
|
|
91
99
|
afterRun: options.afterRun,
|
|
92
100
|
beforeRun: options.beforeRun,
|
|
@@ -94,11 +102,11 @@ class CronLifecycleService {
|
|
|
94
102
|
distributed: options.distributed ?? true,
|
|
95
103
|
expression,
|
|
96
104
|
kind: 'cron',
|
|
97
|
-
lockKey: createLockKey(this.options.distributed.keyPrefix, options.key ??
|
|
105
|
+
lockKey: createLockKey(this.options.distributed.keyPrefix, options.key ?? taskName),
|
|
98
106
|
lockTtlMs: options.lockTtlMs ?? this.options.distributed.lockTtlMs,
|
|
99
107
|
onError: options.onError,
|
|
100
108
|
onSuccess: options.onSuccess,
|
|
101
|
-
taskName
|
|
109
|
+
taskName,
|
|
102
110
|
timezone: options.timezone
|
|
103
111
|
}, 'dynamic');
|
|
104
112
|
}
|
|
@@ -112,20 +120,20 @@ class CronLifecycleService {
|
|
|
112
120
|
* @param options Optional hooks and distributed lock overrides.
|
|
113
121
|
*/
|
|
114
122
|
addInterval(name, ms, callback, options = {}) {
|
|
115
|
-
assertValidTaskName(name);
|
|
116
123
|
assertValidMs(ms, 'scheduling registry');
|
|
124
|
+
const taskName = resolveDynamicTaskName(name, options.name);
|
|
117
125
|
this.registerTask({
|
|
118
126
|
afterRun: options.afterRun,
|
|
119
127
|
beforeRun: options.beforeRun,
|
|
120
128
|
callback,
|
|
121
129
|
distributed: options.distributed ?? true,
|
|
122
130
|
kind: 'interval',
|
|
123
|
-
lockKey: createLockKey(this.options.distributed.keyPrefix, options.key ??
|
|
131
|
+
lockKey: createLockKey(this.options.distributed.keyPrefix, options.key ?? taskName),
|
|
124
132
|
lockTtlMs: options.lockTtlMs ?? this.options.distributed.lockTtlMs,
|
|
125
133
|
ms,
|
|
126
134
|
onError: options.onError,
|
|
127
135
|
onSuccess: options.onSuccess,
|
|
128
|
-
taskName
|
|
136
|
+
taskName
|
|
129
137
|
}, 'dynamic');
|
|
130
138
|
}
|
|
131
139
|
|
|
@@ -138,20 +146,20 @@ class CronLifecycleService {
|
|
|
138
146
|
* @param options Optional hooks and distributed lock overrides.
|
|
139
147
|
*/
|
|
140
148
|
addTimeout(name, ms, callback, options = {}) {
|
|
141
|
-
assertValidTaskName(name);
|
|
142
149
|
assertValidMs(ms, 'scheduling registry');
|
|
150
|
+
const taskName = resolveDynamicTaskName(name, options.name);
|
|
143
151
|
this.registerTask({
|
|
144
152
|
afterRun: options.afterRun,
|
|
145
153
|
beforeRun: options.beforeRun,
|
|
146
154
|
callback,
|
|
147
155
|
distributed: options.distributed ?? true,
|
|
148
156
|
kind: 'timeout',
|
|
149
|
-
lockKey: createLockKey(this.options.distributed.keyPrefix, options.key ??
|
|
157
|
+
lockKey: createLockKey(this.options.distributed.keyPrefix, options.key ?? taskName),
|
|
150
158
|
lockTtlMs: options.lockTtlMs ?? this.options.distributed.lockTtlMs,
|
|
151
159
|
ms,
|
|
152
160
|
onError: options.onError,
|
|
153
161
|
onSuccess: options.onSuccess,
|
|
154
|
-
taskName
|
|
162
|
+
taskName
|
|
155
163
|
}, 'dynamic');
|
|
156
164
|
}
|
|
157
165
|
|
|
@@ -272,6 +280,41 @@ class CronLifecycleService {
|
|
|
272
280
|
throw error;
|
|
273
281
|
}
|
|
274
282
|
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Replaces the millisecond cadence of one existing interval task.
|
|
286
|
+
*
|
|
287
|
+
* @param name Name of the interval task to update.
|
|
288
|
+
* @param ms New positive interval in milliseconds.
|
|
289
|
+
*/
|
|
290
|
+
updateIntervalMs(name, ms) {
|
|
291
|
+
assertValidMs(ms, 'scheduling registry');
|
|
292
|
+
const task = this.tasks.get(name);
|
|
293
|
+
if (!task) {
|
|
294
|
+
throw new Error(`Scheduling task "${name}" does not exist.`);
|
|
295
|
+
}
|
|
296
|
+
if (task.descriptor.kind !== 'interval') {
|
|
297
|
+
throw new Error(`updateIntervalMs() supports only interval tasks. Received ${task.descriptor.kind} task "${name}".`);
|
|
298
|
+
}
|
|
299
|
+
if (!task.enabled || !this.started) {
|
|
300
|
+
task.descriptor.ms = ms;
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const previousMs = task.descriptor.ms;
|
|
304
|
+
const previousHandle = task.scheduledHandle;
|
|
305
|
+
task.descriptor.ms = ms;
|
|
306
|
+
try {
|
|
307
|
+
const nextHandle = this.createScheduledHandle(task);
|
|
308
|
+
task.scheduledHandle = nextHandle;
|
|
309
|
+
if (previousHandle) {
|
|
310
|
+
this.stopScheduledHandle(previousHandle);
|
|
311
|
+
}
|
|
312
|
+
} catch (error) {
|
|
313
|
+
task.descriptor.ms = previousMs;
|
|
314
|
+
task.scheduledHandle = previousHandle;
|
|
315
|
+
throw error;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
275
318
|
async onApplicationBootstrap() {
|
|
276
319
|
if (this.started) {
|
|
277
320
|
return;
|
|
@@ -313,6 +356,7 @@ class CronLifecycleService {
|
|
|
313
356
|
lockRenewalFailures: this.distributedLocks.renewalFailures,
|
|
314
357
|
ownedLocks: this.distributedLocks.ownedLocks,
|
|
315
358
|
redisDependencyResolved: this.distributedLocks.resolvedClient !== undefined,
|
|
359
|
+
redisLockIoAvailable: this.distributedLocks.lockIoAvailable,
|
|
316
360
|
runningTasks,
|
|
317
361
|
totalTasks: this.tasks.size
|
|
318
362
|
});
|
|
@@ -337,11 +381,18 @@ class CronLifecycleService {
|
|
|
337
381
|
async shutdown() {
|
|
338
382
|
if (this.shutdownPromise) {
|
|
339
383
|
await this.shutdownPromise;
|
|
384
|
+
await this.retryReleasedDistributedLocksAfterShutdown();
|
|
340
385
|
return;
|
|
341
386
|
}
|
|
342
387
|
this.shutdownPromise = this.runShutdownLifecycle();
|
|
343
388
|
await this.shutdownPromise;
|
|
344
389
|
}
|
|
390
|
+
async retryReleasedDistributedLocksAfterShutdown() {
|
|
391
|
+
if (this.lifecycleState !== 'stopped' || this.activeTasks.size > 0) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
await this.distributedLocks.releaseOwnedLocks();
|
|
395
|
+
}
|
|
345
396
|
async startLifecycle() {
|
|
346
397
|
await this.distributedLocks.resolveClient();
|
|
347
398
|
this.validateDistributedLockConfiguration();
|
|
@@ -518,8 +569,11 @@ class CronLifecycleService {
|
|
|
518
569
|
});
|
|
519
570
|
} finally {
|
|
520
571
|
lockRenewalMonitor.stop();
|
|
521
|
-
await this.distributedLocks.releaseLock(descriptor);
|
|
522
572
|
this.runningDistributedLockKeys.delete(descriptor.lockKey);
|
|
573
|
+
const released = await this.distributedLocks.releaseLock(descriptor);
|
|
574
|
+
if (!released && this.lifecycleState === 'stopped') {
|
|
575
|
+
await this.distributedLocks.releaseOwnedLocks();
|
|
576
|
+
}
|
|
523
577
|
}
|
|
524
578
|
}
|
|
525
579
|
async waitForActiveTasks() {
|
package/dist/status.d.ts
CHANGED
package/dist/status.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEvG,qEAAqE;AACrE,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtG,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,kBAAkB,CAAC;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB,EAAE,OAAO,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qFAAqF;AACrF,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEvG,qEAAqE;AACrE,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtG,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,kBAAkB,CAAC;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB,EAAE,OAAO,CAAC;IACjC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qFAAqF;AACrF,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAuGD;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,sBAAsB,GAAG,0BAA0B,CAyB1G"}
|
package/dist/status.js
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
/** Cron-specific platform snapshot returned to health and readiness integrations. */
|
|
6
6
|
|
|
7
7
|
function createReadiness(input) {
|
|
8
|
+
const redisLockIoAvailable = resolveRedisLockIoAvailable(input);
|
|
8
9
|
if (input.lifecycleState === 'ready') {
|
|
9
|
-
if (input.distributedEnabled && !input.redisDependencyResolved) {
|
|
10
|
+
if (input.distributedEnabled && (!input.redisDependencyResolved || !redisLockIoAvailable)) {
|
|
10
11
|
return {
|
|
11
12
|
critical: true,
|
|
12
13
|
reason: 'Distributed cron mode requires a ready Redis lock client.',
|
|
@@ -53,6 +54,7 @@ function createReadiness(input) {
|
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
56
|
function createHealth(input) {
|
|
57
|
+
const redisLockIoAvailable = resolveRedisLockIoAvailable(input);
|
|
56
58
|
if (input.lifecycleState === 'failed' || input.lifecycleState === 'stopped') {
|
|
57
59
|
return {
|
|
58
60
|
reason: 'Cron scheduler is unavailable.',
|
|
@@ -65,6 +67,12 @@ function createHealth(input) {
|
|
|
65
67
|
status: 'degraded'
|
|
66
68
|
};
|
|
67
69
|
}
|
|
70
|
+
if (input.distributedEnabled && (!input.redisDependencyResolved || !redisLockIoAvailable)) {
|
|
71
|
+
return {
|
|
72
|
+
reason: 'Distributed cron Redis lock I/O is unavailable.',
|
|
73
|
+
status: 'unhealthy'
|
|
74
|
+
};
|
|
75
|
+
}
|
|
68
76
|
if (input.lockRenewalFailures > 0 || input.lockOwnershipLosses > 0) {
|
|
69
77
|
return {
|
|
70
78
|
reason: 'Distributed cron lock renewal reported recoverable failures.',
|
|
@@ -75,6 +83,12 @@ function createHealth(input) {
|
|
|
75
83
|
status: 'healthy'
|
|
76
84
|
};
|
|
77
85
|
}
|
|
86
|
+
function resolveRedisLockIoAvailable(input) {
|
|
87
|
+
if (!input.distributedEnabled) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return input.redisLockIoAvailable ?? input.redisDependencyResolved;
|
|
91
|
+
}
|
|
78
92
|
|
|
79
93
|
/**
|
|
80
94
|
* Creates the cron platform snapshot consumed by status reporters.
|
|
@@ -83,6 +97,7 @@ function createHealth(input) {
|
|
|
83
97
|
* @returns Readiness, health, ownership, and cron detail fields.
|
|
84
98
|
*/
|
|
85
99
|
export function createCronPlatformStatusSnapshot(input) {
|
|
100
|
+
const redisLockIoAvailable = resolveRedisLockIoAvailable(input);
|
|
86
101
|
return {
|
|
87
102
|
details: {
|
|
88
103
|
activeTicks: input.activeTicks,
|
|
@@ -94,6 +109,7 @@ export function createCronPlatformStatusSnapshot(input) {
|
|
|
94
109
|
lockRenewalFailures: input.lockRenewalFailures,
|
|
95
110
|
ownedLocks: input.ownedLocks,
|
|
96
111
|
redisDependencyResolved: input.redisDependencyResolved,
|
|
112
|
+
redisLockIoAvailable,
|
|
97
113
|
runningTasks: input.runningTasks,
|
|
98
114
|
totalTasks: input.totalTasks
|
|
99
115
|
},
|
package/dist/types.d.ts
CHANGED
|
@@ -204,5 +204,12 @@ export interface SchedulingRegistry {
|
|
|
204
204
|
* @param expression New cron expression validated before rescheduling.
|
|
205
205
|
*/
|
|
206
206
|
updateCronExpression(name: string, expression: string): void;
|
|
207
|
+
/**
|
|
208
|
+
* Replaces the millisecond cadence for an existing interval task.
|
|
209
|
+
*
|
|
210
|
+
* @param name Task name to update.
|
|
211
|
+
* @param ms New positive interval in milliseconds.
|
|
212
|
+
*/
|
|
213
|
+
updateIntervalMs(name: string, ms: number): void;
|
|
207
214
|
}
|
|
208
215
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"timeout",
|
|
10
10
|
"distributed-lock"
|
|
11
11
|
],
|
|
12
|
-
"version": "1.0
|
|
12
|
+
"version": "1.1.0",
|
|
13
13
|
"private": false,
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"repository": {
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"croner": "^8.1.2",
|
|
40
40
|
"@fluojs/core": "^1.0.3",
|
|
41
|
-
"@fluojs/
|
|
42
|
-
"@fluojs/
|
|
41
|
+
"@fluojs/di": "^1.1.0",
|
|
42
|
+
"@fluojs/runtime": "^1.1.8"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@fluojs/redis": "^1.0.
|
|
45
|
+
"@fluojs/redis": "^1.0.2"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"@fluojs/redis": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"vitest": "^3.2.4",
|
|
54
|
-
"@fluojs/redis": "^1.0.
|
|
54
|
+
"@fluojs/redis": "^1.0.2"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"prebuild": "node ../../tooling/scripts/clean-dist.mjs",
|