@push.rocks/smarttime 4.1.0 → 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_bundle/bundle.js +1 -1
- package/dist_bundle/bundle.js.map +2 -2
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/smarttime.classes.cronjob.js +4 -2
- package/dist_ts/smarttime.classes.cronmanager.d.ts +6 -0
- package/dist_ts/smarttime.classes.cronmanager.js +44 -20
- package/dist_ts/smarttime.units.js +2 -2
- package/npmextra.json +8 -0
- package/package.json +18 -18
- package/readme.md +200 -64
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/smarttime.classes.cronjob.ts +3 -2
- package/ts/smarttime.classes.cronmanager.ts +47 -27
- package/ts/smarttime.units.ts +1 -1
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import * as plugins from './smarttime.plugins.js';
|
|
2
2
|
import { CronManager } from './smarttime.classes.cronmanager.js';
|
|
3
3
|
|
|
4
|
-
import { CronParser } from './smarttime.classes.cronparser.js';
|
|
5
|
-
|
|
6
4
|
export type TJobFunction =
|
|
7
5
|
| ((triggerTimeArg?: number) => void)
|
|
8
6
|
| ((triggerTimeArg?: number) => Promise<any>);
|
|
@@ -24,6 +22,9 @@ export class CronJob {
|
|
|
24
22
|
* checks wether the cronjob needs to be executed
|
|
25
23
|
*/
|
|
26
24
|
public checkExecution(): number {
|
|
25
|
+
if (this.status === 'stopped') {
|
|
26
|
+
return this.nextExecutionUnix;
|
|
27
|
+
}
|
|
27
28
|
if (this.nextExecutionUnix === 0) {
|
|
28
29
|
this.getNextExecutionTime();
|
|
29
30
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as plugins from './smarttime.plugins.js';
|
|
2
2
|
import { CronJob, type TJobFunction } from './smarttime.classes.cronjob.js';
|
|
3
|
-
import { getMilliSecondsAsHumanReadableString } from './smarttime.units.js';
|
|
4
3
|
|
|
5
4
|
export class CronManager {
|
|
6
5
|
public executionTimeout: plugins.smartdelay.Timeout<void>;
|
|
@@ -8,13 +7,26 @@ export class CronManager {
|
|
|
8
7
|
public status: 'started' | 'stopped' = 'stopped';
|
|
9
8
|
public cronjobs = new plugins.lik.ObjectMap<CronJob>();
|
|
10
9
|
|
|
10
|
+
private cycleWakeDeferred: plugins.smartpromise.Deferred<void> | null = null;
|
|
11
|
+
|
|
11
12
|
constructor() {}
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Resolves the current wake deferred, causing the sleeping cycle
|
|
16
|
+
* to immediately recalculate instead of waiting for its timeout.
|
|
17
|
+
*/
|
|
18
|
+
private wakeCycle() {
|
|
19
|
+
if (this.cycleWakeDeferred && this.cycleWakeDeferred.status === 'pending') {
|
|
20
|
+
this.cycleWakeDeferred.resolve();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
public addCronjob(cronIdentifierArg: string, cronFunctionArg: TJobFunction) {
|
|
14
25
|
const newCronJob = new CronJob(this, cronIdentifierArg, cronFunctionArg);
|
|
15
26
|
this.cronjobs.add(newCronJob);
|
|
16
27
|
if (this.status === 'started') {
|
|
17
28
|
newCronJob.start();
|
|
29
|
+
this.wakeCycle();
|
|
18
30
|
}
|
|
19
31
|
|
|
20
32
|
return newCronJob;
|
|
@@ -23,6 +35,9 @@ export class CronManager {
|
|
|
23
35
|
public removeCronjob(cronjobArg: CronJob) {
|
|
24
36
|
cronjobArg.stop();
|
|
25
37
|
this.cronjobs.remove(cronjobArg);
|
|
38
|
+
if (this.status === 'started') {
|
|
39
|
+
this.wakeCycle();
|
|
40
|
+
}
|
|
26
41
|
}
|
|
27
42
|
|
|
28
43
|
/**
|
|
@@ -39,35 +54,39 @@ export class CronManager {
|
|
|
39
54
|
}
|
|
40
55
|
|
|
41
56
|
private async runCronCycle() {
|
|
42
|
-
this.
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
while (this.status === 'started') {
|
|
58
|
+
// Create a fresh wake signal for this iteration
|
|
59
|
+
this.cycleWakeDeferred = new plugins.smartpromise.Deferred<void>();
|
|
60
|
+
|
|
61
|
+
// Check all cronjobs and find the soonest next execution
|
|
62
|
+
let soonestMs = Infinity;
|
|
45
63
|
for (const cronJob of this.cronjobs.getArray()) {
|
|
46
64
|
cronJob.checkExecution();
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
) {
|
|
51
|
-
nextRunningCronjob = cronJob;
|
|
65
|
+
const msToNext = cronJob.getTimeToNextExecution();
|
|
66
|
+
if (msToNext < soonestMs) {
|
|
67
|
+
soonestMs = msToNext;
|
|
52
68
|
}
|
|
53
69
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
|
|
71
|
+
// Sleep until the next job is due or until woken by a lifecycle event
|
|
72
|
+
if (soonestMs < Infinity && soonestMs > 0) {
|
|
73
|
+
this.executionTimeout = new plugins.smartdelay.Timeout(soonestMs);
|
|
74
|
+
await Promise.race([
|
|
75
|
+
this.executionTimeout.promise,
|
|
76
|
+
this.cycleWakeDeferred.promise,
|
|
77
|
+
]);
|
|
78
|
+
// Cancel the timeout to avoid lingering timers
|
|
79
|
+
this.executionTimeout.cancel();
|
|
80
|
+
} else if (soonestMs <= 0) {
|
|
81
|
+
// Job is overdue, loop immediately to execute it
|
|
82
|
+
continue;
|
|
63
83
|
} else {
|
|
64
|
-
|
|
65
|
-
|
|
84
|
+
// No jobs — wait indefinitely until woken by addCronjob or stop
|
|
85
|
+
await this.cycleWakeDeferred.promise;
|
|
66
86
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
};
|
|
87
|
+
}
|
|
88
|
+
this.cycleWakeDeferred = null;
|
|
89
|
+
}
|
|
71
90
|
|
|
72
91
|
/**
|
|
73
92
|
* stops all cronjobs
|
|
@@ -75,9 +94,10 @@ export class CronManager {
|
|
|
75
94
|
public stop() {
|
|
76
95
|
if (this.status === 'started') {
|
|
77
96
|
this.status = 'stopped';
|
|
78
|
-
this.executionTimeout
|
|
79
|
-
|
|
80
|
-
|
|
97
|
+
if (this.executionTimeout) {
|
|
98
|
+
this.executionTimeout.cancel();
|
|
99
|
+
}
|
|
100
|
+
this.wakeCycle();
|
|
81
101
|
}
|
|
82
102
|
for (const cron of this.cronjobs.getArray()) {
|
|
83
103
|
cron.stop();
|
package/ts/smarttime.units.ts
CHANGED
|
@@ -69,5 +69,5 @@ export const getMilliSecondsAsHumanReadableString = (milliSecondsArg: number): s
|
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
export const getMilliSecondsAsHumanReadableAgoTime = (timeStampArg: number): string => {
|
|
72
|
-
return plugins.dateFns.formatDistanceToNow(timeStampArg);
|
|
72
|
+
return plugins.dateFns.formatDistanceToNow(new Date(timeStampArg));
|
|
73
73
|
}
|