@live-change/cron-service 0.9.163 → 0.9.165
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/config.js +3 -1
- package/interval.js +103 -24
- package/package.json +3 -3
- package/run.js +30 -11
- package/schedule.js +103 -13
package/config.js
CHANGED
|
@@ -2,12 +2,14 @@ import definition from './definition.js'
|
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
4
|
adminRoles = ['admin', 'owner'],
|
|
5
|
+
readerRoles = ['reader'],
|
|
5
6
|
ownerTypes = ['user_User'],
|
|
6
|
-
topicTypes =
|
|
7
|
+
topicTypes = undefined
|
|
7
8
|
} = definition.config
|
|
8
9
|
|
|
9
10
|
const config = {
|
|
10
11
|
adminRoles,
|
|
12
|
+
readerRoles,
|
|
11
13
|
ownerTypes,
|
|
12
14
|
topicTypes
|
|
13
15
|
}
|
package/interval.js
CHANGED
|
@@ -3,7 +3,7 @@ const app = App.app()
|
|
|
3
3
|
|
|
4
4
|
import definition from './definition.js'
|
|
5
5
|
import config from './config.js'
|
|
6
|
-
import { triggerType } from './run.js'
|
|
6
|
+
import { triggerType, runTrigger, doRunTrigger, waitForTasks, RunState } from './run.js'
|
|
7
7
|
|
|
8
8
|
export const Interval = definition.model({
|
|
9
9
|
name: "Interval",
|
|
@@ -15,31 +15,85 @@ export const Interval = definition.model({
|
|
|
15
15
|
roles: config.adminRoles
|
|
16
16
|
},
|
|
17
17
|
readAccessControl: {
|
|
18
|
-
roles: config.adminRoles
|
|
18
|
+
roles: [...config.adminRoles, ...config.readerRoles]
|
|
19
19
|
},
|
|
20
20
|
readAllAccess: ['admin'],
|
|
21
21
|
},
|
|
22
22
|
properties: {
|
|
23
23
|
description: {
|
|
24
24
|
type: String,
|
|
25
|
-
description: "Description of the interval"
|
|
25
|
+
description: "Description of the interval",
|
|
26
|
+
input: 'textarea',
|
|
26
27
|
},
|
|
27
28
|
interval: {
|
|
28
29
|
type: Number, // milliseconds
|
|
29
|
-
description: "Interval between triggers in milliseconds"
|
|
30
|
+
description: "Interval between triggers in milliseconds",
|
|
31
|
+
validation: ['nonEmpty', 'integer'],
|
|
32
|
+
input: 'integer',
|
|
33
|
+
inputConfig: {
|
|
34
|
+
attributes: {
|
|
35
|
+
suffix: ' ms',
|
|
36
|
+
showButtons: true,
|
|
37
|
+
step: 1000,
|
|
38
|
+
min: 1000,
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
firstRunDelay: {
|
|
43
|
+
type: Number, // milliseconds
|
|
44
|
+
description: "Delay before first run",
|
|
45
|
+
input: 'integer',
|
|
46
|
+
inputConfig: {
|
|
47
|
+
attributes: {
|
|
48
|
+
suffix: ' ms',
|
|
49
|
+
showButtons: true,
|
|
50
|
+
step: 1000,
|
|
51
|
+
min: 0,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
30
54
|
},
|
|
31
55
|
wait: {
|
|
32
56
|
type: Number, // milliseconds
|
|
33
|
-
description: "Wait for previous trigger to finish before planning next trigger"
|
|
57
|
+
description: "Wait for previous trigger to finish before planning next trigger",
|
|
58
|
+
input: 'integer',
|
|
59
|
+
inputConfig: {
|
|
60
|
+
attributes: {
|
|
61
|
+
suffix: ' ms',
|
|
62
|
+
showButtons: true,
|
|
63
|
+
step: 1000,
|
|
64
|
+
min: 0,
|
|
65
|
+
}
|
|
66
|
+
}
|
|
34
67
|
},
|
|
35
68
|
trigger: triggerType
|
|
36
69
|
}
|
|
37
70
|
})
|
|
38
71
|
|
|
39
|
-
|
|
72
|
+
export const IntervalInfo = definition.model({
|
|
73
|
+
name: "IntervalInfo",
|
|
74
|
+
propertyOf: {
|
|
75
|
+
what: Interval,
|
|
76
|
+
readAccessControl: {
|
|
77
|
+
roles: [...config.adminRoles, ...config.readerRoles]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
properties: {
|
|
81
|
+
lastRun: {
|
|
82
|
+
type: Date
|
|
83
|
+
},
|
|
84
|
+
nextRun: {
|
|
85
|
+
type: Date
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
async function processInterval({ id, interval, wait, trigger, firstRunDelay, isFirstRun }, { triggerService }) {
|
|
91
|
+
//console.log("PROCESSING INTERVAL", id, interval, wait, trigger, firstRunDelay, isFirstRun)
|
|
40
92
|
if(wait) await waitForTasks('cron_Interval', id)
|
|
41
|
-
|
|
93
|
+
//console.log("WAIT FOR TASKS DONE", id)
|
|
94
|
+
const nextTimestamp = Date.now() + (isFirstRun ? (firstRunDelay || 0) : interval)
|
|
42
95
|
const nextTime = new Date(nextTimestamp)
|
|
96
|
+
//console.log("NEXT TIME", nextTime)
|
|
43
97
|
await triggerService({
|
|
44
98
|
service: 'timer',
|
|
45
99
|
type: 'createTimer',
|
|
@@ -59,6 +113,11 @@ async function processInterval({ id, interval, wait, trigger }) {
|
|
|
59
113
|
}
|
|
60
114
|
}
|
|
61
115
|
})
|
|
116
|
+
await IntervalInfo.update(id, {
|
|
117
|
+
id,
|
|
118
|
+
nextRun: nextTime
|
|
119
|
+
})
|
|
120
|
+
//console.log("TIMER CREATED", id)
|
|
62
121
|
}
|
|
63
122
|
|
|
64
123
|
|
|
@@ -73,22 +132,34 @@ definition.trigger({
|
|
|
73
132
|
const intervalData = await Interval.get(interval)
|
|
74
133
|
if(!intervalData) return /// interval was deleted
|
|
75
134
|
if(intervalData.wait) {
|
|
135
|
+
const lastRun = new Date()
|
|
76
136
|
await runTrigger(intervalData.trigger, {
|
|
77
137
|
trigger,
|
|
78
138
|
triggerService,
|
|
79
139
|
jobType: 'cron_Interval',
|
|
80
140
|
job: interval,
|
|
81
|
-
timeout: Number.isInteger(intervalData.wait) ? intervalData.wait : undefined
|
|
141
|
+
timeout: Number.isInteger(intervalData.wait) ? intervalData.wait : undefined,
|
|
142
|
+
runTime: lastRun
|
|
82
143
|
})
|
|
83
|
-
await
|
|
144
|
+
await IntervalInfo.update(interval, {
|
|
145
|
+
id: interval,
|
|
146
|
+
lastRun
|
|
147
|
+
})
|
|
148
|
+
await processInterval(intervalData, { triggerService })
|
|
84
149
|
} else {
|
|
85
|
-
await processInterval(intervalData) // no wait, process immediately
|
|
150
|
+
await processInterval(intervalData, { triggerService }) // no wait, process immediately
|
|
86
151
|
try {
|
|
152
|
+
const lastRun = new Date()
|
|
87
153
|
await doRunTrigger(intervalData.trigger, {
|
|
88
154
|
trigger,
|
|
89
155
|
triggerService,
|
|
90
156
|
jobType: 'cron_Interval',
|
|
91
|
-
job: interval
|
|
157
|
+
job: interval,
|
|
158
|
+
runTime: lastRun
|
|
159
|
+
})
|
|
160
|
+
await IntervalInfo.update(interval, {
|
|
161
|
+
id: interval,
|
|
162
|
+
lastRun
|
|
92
163
|
})
|
|
93
164
|
} catch(error) {
|
|
94
165
|
console.error("ERROR RUNNING INTERVAL TRIGGER", error)
|
|
@@ -116,27 +187,28 @@ definition.trigger({
|
|
|
116
187
|
if(oldData) { // clear old version
|
|
117
188
|
await triggerService({
|
|
118
189
|
service: 'timer',
|
|
119
|
-
type: 'cancelTimerIfExists',
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
190
|
+
type: 'cancelTimerIfExists',
|
|
191
|
+
}, {
|
|
192
|
+
timer: 'cron_Interval_' + object
|
|
123
193
|
})
|
|
124
194
|
if(!data) { // full cleanup
|
|
125
195
|
await triggerService({
|
|
126
196
|
service: 'timer',
|
|
127
|
-
type: 'cancelTimerIfExists',
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
197
|
+
type: 'cancelTimerIfExists',
|
|
198
|
+
}, {
|
|
199
|
+
timer: 'cron_run_timeout_' + object
|
|
131
200
|
})
|
|
132
|
-
RunState.delete(App.encodeIdentifier(['cron_Interval', object
|
|
201
|
+
RunState.delete(App.encodeIdentifier(['cron_Interval', object]))
|
|
133
202
|
}
|
|
134
203
|
}
|
|
135
204
|
if(data) { // setup new version
|
|
205
|
+
console.log("PROCESSING INTERVAL", object, data)
|
|
136
206
|
await processInterval({
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
207
|
+
id: object,
|
|
208
|
+
...data,
|
|
209
|
+
isFirstRun: !oldData
|
|
210
|
+
}, { triggerService })
|
|
211
|
+
console.log("PROCESSING INTERVAL DONE", object, data)
|
|
140
212
|
}
|
|
141
213
|
}
|
|
142
214
|
})
|
|
@@ -156,7 +228,14 @@ definition.afterStart(async (service) => {
|
|
|
156
228
|
const existingTimer = await Timer.get('cron_Interval_' + interval.id)
|
|
157
229
|
if(!existingTimer) {
|
|
158
230
|
console.error("INTERVAL", interval, "HAS NO TIMER, REPROCESSING")
|
|
159
|
-
await processInterval(interval
|
|
231
|
+
await processInterval(interval, {
|
|
232
|
+
triggerService: (trigger, data, returnArray = false) =>
|
|
233
|
+
app.triggerService({
|
|
234
|
+
...trigger,
|
|
235
|
+
causeType: 'cron_Interval',
|
|
236
|
+
cause: 'cron_Interval_' + interval.id,
|
|
237
|
+
}, data, returnArray)
|
|
238
|
+
})
|
|
160
239
|
}
|
|
161
240
|
}
|
|
162
241
|
} while(bucket.length === bucketSize)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/cron-service",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.165",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"type": "module",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@live-change/framework": "^0.9.
|
|
25
|
+
"@live-change/framework": "^0.9.165"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "687dab16bd0c6594544cdab70cd7eecc17bb510c"
|
|
28
28
|
}
|
package/run.js
CHANGED
|
@@ -4,12 +4,16 @@ const app = App.app()
|
|
|
4
4
|
import definition from './definition.js'
|
|
5
5
|
|
|
6
6
|
const Task = definition.foreignModel('task', 'Task')
|
|
7
|
+
import config from './config.js'
|
|
7
8
|
|
|
8
9
|
export const RunState = definition.model({
|
|
9
10
|
name: "RunState",
|
|
10
11
|
propertyOfAny: {
|
|
11
12
|
to: ['job'],
|
|
12
|
-
jobTypes: ['cron_Interval', 'cron_Schedule']
|
|
13
|
+
jobTypes: ['cron_Interval', 'cron_Schedule'],
|
|
14
|
+
readAccessControl: {
|
|
15
|
+
roles: [...config.adminRoles, ...config.readerRoles]
|
|
16
|
+
}
|
|
13
17
|
},
|
|
14
18
|
properties: {
|
|
15
19
|
state: {
|
|
@@ -37,43 +41,57 @@ export const RunState = definition.model({
|
|
|
37
41
|
}
|
|
38
42
|
})
|
|
39
43
|
|
|
40
|
-
|
|
41
44
|
export const triggerType = {
|
|
42
45
|
description: "Trigger to schedule",
|
|
43
|
-
input: '
|
|
46
|
+
input: 'trigger',
|
|
44
47
|
type: Object,
|
|
45
48
|
properties: {
|
|
46
49
|
name: {
|
|
47
50
|
description: "Trigger name",
|
|
48
51
|
type: String,
|
|
52
|
+
validation: ['nonEmpty']
|
|
49
53
|
},
|
|
50
54
|
service: {
|
|
51
55
|
description: "Service holding the trigger, or null for triggering any service",
|
|
52
56
|
type: String,
|
|
57
|
+
validation: ['nonEmpty']
|
|
53
58
|
},
|
|
54
59
|
properties: {
|
|
55
60
|
description: "Properties to pass to the trigger",
|
|
56
|
-
type: Object,
|
|
61
|
+
type: Object,
|
|
62
|
+
input: 'json',
|
|
63
|
+
defaultValue: {}
|
|
64
|
+
},
|
|
65
|
+
returnTask: {
|
|
66
|
+
description: "Return task to wait for",
|
|
67
|
+
type: Boolean,
|
|
68
|
+
defaultValue: false
|
|
57
69
|
}
|
|
58
70
|
}
|
|
59
71
|
}
|
|
60
72
|
|
|
61
|
-
export async function doRunTrigger(triggerInfo, { trigger, triggerService, jobType, job }) {
|
|
73
|
+
export async function doRunTrigger(triggerInfo, { trigger, triggerService, jobType, job, runTime }) {
|
|
62
74
|
if(triggerInfo.service) {
|
|
63
75
|
return await triggerService({
|
|
64
76
|
type: triggerInfo.name,
|
|
65
77
|
service: triggerInfo.service,
|
|
66
78
|
causeType: jobType, cause: job
|
|
67
|
-
},
|
|
79
|
+
}, {
|
|
80
|
+
...triggerInfo.properties,
|
|
81
|
+
jobRunTime: runTime
|
|
82
|
+
}, true)
|
|
68
83
|
} else {
|
|
69
84
|
return await trigger({
|
|
70
85
|
type: triggerInfo.name,
|
|
71
86
|
causeType: jobType, cause: job
|
|
72
|
-
},
|
|
87
|
+
}, {
|
|
88
|
+
...triggerInfo.properties,
|
|
89
|
+
jobRunTime: runTime
|
|
90
|
+
})
|
|
73
91
|
}
|
|
74
92
|
}
|
|
75
93
|
|
|
76
|
-
export async function runTrigger(triggerInfo, { trigger, triggerService, jobType, job, timeout }) {
|
|
94
|
+
export async function runTrigger(triggerInfo, { trigger, triggerService, jobType, job, timeout, runTime }) {
|
|
77
95
|
const id = App.encodeIdentifier([jobType, job])
|
|
78
96
|
await RunState.create({
|
|
79
97
|
id,
|
|
@@ -104,13 +122,13 @@ export async function runTrigger(triggerInfo, { trigger, triggerService, jobType
|
|
|
104
122
|
}
|
|
105
123
|
let triggerResults = []
|
|
106
124
|
try {
|
|
107
|
-
triggerResults = await doRunTrigger(triggerInfo, { trigger, triggerService, jobType, job })
|
|
125
|
+
triggerResults = await doRunTrigger(triggerInfo, { trigger, triggerService, jobType, job, runTime })
|
|
108
126
|
} catch(error) {
|
|
109
127
|
console.error("ERROR RUNNING TRIGGER", error)
|
|
110
128
|
/// Ignore error, it will be handled by the task service
|
|
111
129
|
}
|
|
112
130
|
if(triggerInfo.returnTask) {
|
|
113
|
-
const tasks = await Promise.all(triggerResults.map((result) => Task.get(result)))
|
|
131
|
+
const tasks = (await Promise.all(triggerResults.map((result) => Task.get(result))))
|
|
114
132
|
.filter(task => task !== undefined)
|
|
115
133
|
.filter(task => task.state !== 'done' && task.state !== 'failed')
|
|
116
134
|
if(tasks.length > 0) {
|
|
@@ -185,7 +203,7 @@ export async function waitForTasks(jobType, job) {
|
|
|
185
203
|
}
|
|
186
204
|
const runStateObservable = RunState.observable(runState)
|
|
187
205
|
const runStateObserver = {
|
|
188
|
-
set: (value) => {
|
|
206
|
+
set: (value) => {
|
|
189
207
|
if(!value) finish()
|
|
190
208
|
if(value.tasks) {
|
|
191
209
|
for(const taskId of value.tasks) {
|
|
@@ -194,6 +212,7 @@ export async function waitForTasks(jobType, job) {
|
|
|
194
212
|
}
|
|
195
213
|
}
|
|
196
214
|
}
|
|
215
|
+
runStateObservable.observe(runStateObserver)
|
|
197
216
|
function finish() {
|
|
198
217
|
if(done) return
|
|
199
218
|
done = true
|
package/schedule.js
CHANGED
|
@@ -3,7 +3,7 @@ const app = App.app()
|
|
|
3
3
|
|
|
4
4
|
import definition from './definition.js'
|
|
5
5
|
import config from './config.js'
|
|
6
|
-
import { triggerType } from './run.js'
|
|
6
|
+
import { triggerType, runTrigger, doRunTrigger, waitForTasks } from './run.js'
|
|
7
7
|
|
|
8
8
|
export const Schedule = definition.model({
|
|
9
9
|
name: "Schedule",
|
|
@@ -21,30 +21,104 @@ export const Schedule = definition.model({
|
|
|
21
21
|
},
|
|
22
22
|
properties: {
|
|
23
23
|
description: {
|
|
24
|
-
type: String
|
|
24
|
+
type: String,
|
|
25
|
+
description: "Description of the schedule",
|
|
26
|
+
input: 'textarea',
|
|
25
27
|
},
|
|
26
28
|
minute: {
|
|
27
|
-
type: Number // NaN for every minute
|
|
29
|
+
type: Number, // NaN for every minute
|
|
30
|
+
description: "Minute of the hour to run the schedule",
|
|
31
|
+
input: 'integer',
|
|
32
|
+
inputConfig: {
|
|
33
|
+
attributes: {
|
|
34
|
+
showButtons: true,
|
|
35
|
+
step: 1,
|
|
36
|
+
min: 0,
|
|
37
|
+
max: 59,
|
|
38
|
+
}
|
|
39
|
+
}
|
|
28
40
|
},
|
|
29
41
|
hour: {
|
|
30
42
|
type: Number, // NaN for every hour
|
|
43
|
+
description: "Hour of the day to run the schedule",
|
|
44
|
+
input: 'integer',
|
|
45
|
+
inputConfig: {
|
|
46
|
+
attributes: {
|
|
47
|
+
showButtons: true,
|
|
48
|
+
step: 1,
|
|
49
|
+
min: 0,
|
|
50
|
+
max: 23,
|
|
51
|
+
}
|
|
52
|
+
}
|
|
31
53
|
},
|
|
32
54
|
day: {
|
|
33
55
|
type: Number, // NaN for every day
|
|
56
|
+
description: "Day of the month to run the schedule",
|
|
57
|
+
input: 'integer',
|
|
58
|
+
inputConfig: {
|
|
59
|
+
attributes: {
|
|
60
|
+
showButtons: true,
|
|
61
|
+
step: 1,
|
|
62
|
+
min: 1,
|
|
63
|
+
max: 31,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
34
66
|
},
|
|
35
67
|
dayOfWeek: {
|
|
36
68
|
type: Number, // NaN for every day of week
|
|
69
|
+
description: "Day of the week to run the schedule",
|
|
70
|
+
input: 'integer',
|
|
71
|
+
inputConfig: {
|
|
72
|
+
attributes: {
|
|
73
|
+
showButtons: true,
|
|
74
|
+
step: 1,
|
|
75
|
+
min: 1,
|
|
76
|
+
max: 7,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
37
79
|
},
|
|
38
80
|
month: {
|
|
39
81
|
type: Number, // NaN for every month
|
|
82
|
+
description: "Month of the year to run the schedule",
|
|
83
|
+
input: 'integer',
|
|
84
|
+
inputConfig: {
|
|
85
|
+
attributes: {
|
|
86
|
+
showButtons: true,
|
|
87
|
+
step: 1,
|
|
88
|
+
min: 1,
|
|
89
|
+
max: 12,
|
|
90
|
+
}
|
|
91
|
+
}
|
|
40
92
|
},
|
|
41
93
|
trigger: triggerType
|
|
42
94
|
}
|
|
43
95
|
})
|
|
44
96
|
|
|
97
|
+
export const ScheduleInfo = definition.model({
|
|
98
|
+
name: "ScheduleInfo",
|
|
99
|
+
propertyOf: {
|
|
100
|
+
what: Schedule,
|
|
101
|
+
readAccessControl: {
|
|
102
|
+
roles: [...config.adminRoles, ...config.readerRoles]
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
properties: {
|
|
106
|
+
lastRun: {
|
|
107
|
+
type: Date
|
|
108
|
+
},
|
|
109
|
+
nextRun: {
|
|
110
|
+
type: Date
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
|
|
45
115
|
function getNextTime(schedule) {
|
|
46
116
|
const now = new Date()
|
|
47
117
|
let time = now
|
|
118
|
+
|
|
119
|
+
/// set to next minute
|
|
120
|
+
time = new Date(time.getFullYear(), time.getMonth(), time.getDate(), time.getHours(), time.getMinutes() + 1, 0)
|
|
121
|
+
|
|
48
122
|
if(Number.isInteger(schedule.minute)) {
|
|
49
123
|
if(time.getMinutes() >= schedule.minute) { // next hour
|
|
50
124
|
time = new Date(time.getFullYear(), time.getMonth(), time.getDate(), time.getHours() + 1, schedule.minute, 0)
|
|
@@ -72,8 +146,8 @@ function getNextTime(schedule) {
|
|
|
72
146
|
return time
|
|
73
147
|
}
|
|
74
148
|
|
|
75
|
-
async function processSchedule({ id, minute, hour, day, dayOfWeek, month, trigger }) {
|
|
76
|
-
const nextTime = getNextTime(
|
|
149
|
+
async function processSchedule({ id, minute, hour, day, dayOfWeek, month, trigger }, { triggerService }) {
|
|
150
|
+
const nextTime = getNextTime({ minute, hour, day, dayOfWeek, month })
|
|
77
151
|
const nextTimestamp = nextTime.getTime()
|
|
78
152
|
await triggerService({
|
|
79
153
|
service: 'timer',
|
|
@@ -94,6 +168,10 @@ async function processSchedule({ id, minute, hour, day, dayOfWeek, month, trigge
|
|
|
94
168
|
}
|
|
95
169
|
}
|
|
96
170
|
})
|
|
171
|
+
await ScheduleInfo.update(id, {
|
|
172
|
+
id,
|
|
173
|
+
nextRun: nextTime
|
|
174
|
+
})
|
|
97
175
|
}
|
|
98
176
|
|
|
99
177
|
definition.trigger({
|
|
@@ -106,18 +184,23 @@ definition.trigger({
|
|
|
106
184
|
execute: async ({ schedule }, { service, trigger, triggerService }, emit) => {
|
|
107
185
|
const scheduleData = await Schedule.get(schedule)
|
|
108
186
|
if(!scheduleData) return /// schedule was deleted
|
|
109
|
-
await processSchedule(scheduleData) // no wait, process immediately
|
|
187
|
+
await processSchedule(scheduleData, { triggerService }) // no wait, process immediately
|
|
110
188
|
try {
|
|
189
|
+
const lastRun = new Date()
|
|
111
190
|
await doRunTrigger(scheduleData.trigger, {
|
|
112
191
|
trigger,
|
|
113
192
|
triggerService,
|
|
114
193
|
jobType: 'cron_Schedule',
|
|
115
|
-
job: schedule
|
|
194
|
+
job: schedule,
|
|
195
|
+
runTime: lastRun
|
|
196
|
+
})
|
|
197
|
+
await ScheduleInfo.update(schedule, {
|
|
198
|
+
id: schedule,
|
|
199
|
+
lastRun
|
|
116
200
|
})
|
|
117
201
|
} catch(error) {
|
|
118
202
|
console.error("ERROR RUNNING SCHEDULE TRIGGER", error)
|
|
119
203
|
}
|
|
120
|
-
|
|
121
204
|
}
|
|
122
205
|
})
|
|
123
206
|
|
|
@@ -140,16 +223,16 @@ definition.trigger({
|
|
|
140
223
|
await triggerService({
|
|
141
224
|
service: 'timer',
|
|
142
225
|
type: 'cancelTimerIfExists',
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
226
|
+
}, {
|
|
227
|
+
timer: 'cron_Schedule_' + object
|
|
146
228
|
})
|
|
229
|
+
await ScheduleInfo.delete(object)
|
|
147
230
|
}
|
|
148
231
|
if(data) {
|
|
149
232
|
await processSchedule({
|
|
150
233
|
id: object,
|
|
151
234
|
...data
|
|
152
|
-
})
|
|
235
|
+
}, { triggerService })
|
|
153
236
|
}
|
|
154
237
|
}
|
|
155
238
|
})
|
|
@@ -170,7 +253,14 @@ definition.afterStart(async (service) => {
|
|
|
170
253
|
const existingTimer = await Timer.get('cron_Schedule_' + schedule.id)
|
|
171
254
|
if(!existingTimer) {
|
|
172
255
|
console.error("SCHEDULE", schedule, "HAS NO TIMER, REPROCESSING")
|
|
173
|
-
await processSchedule(schedule
|
|
256
|
+
await processSchedule(schedule, {
|
|
257
|
+
triggerService: (trigger, data, returnArray = false) =>
|
|
258
|
+
app.triggerService({
|
|
259
|
+
...trigger,
|
|
260
|
+
causeType: 'cron_Schedule',
|
|
261
|
+
cause: 'cron_Schedule_' + schedule.id,
|
|
262
|
+
}, data, returnArray)
|
|
263
|
+
})
|
|
174
264
|
}
|
|
175
265
|
}
|
|
176
266
|
})
|