(date: Date)
| 161 | }; |
| 162 | |
| 163 | const runTask = (date: Date): Promise<any> => { |
| 164 | return new Promise(async (resolve) => { |
| 165 | const execution: Execution = { |
| 166 | id: createID(), |
| 167 | reason: 'scheduled' |
| 168 | } |
| 169 | |
| 170 | const shouldExecute = await this.beforeRun(date, execution); |
| 171 | const randomDelay = Math.floor(Math.random() * this.maxRandomDelay); |
| 172 | |
| 173 | if(shouldExecute){ |
| 174 | const execute = async () => { |
| 175 | try { |
| 176 | this.runCount++; |
| 177 | execution.startedAt = new Date(); |
| 178 | const result = await this.onMatch(date, execution); |
| 179 | execution.finishedAt = new Date(); |
| 180 | execution.result = result; |
| 181 | this.onFinished(date, execution); |
| 182 | |
| 183 | if( this.maxExecutions && this.runCount >= this.maxExecutions){ |
| 184 | this.onMaxExecutions(date); |
| 185 | this.stop(); |
| 186 | } |
| 187 | } catch (error: any){ |
| 188 | execution.finishedAt = new Date(); |
| 189 | execution.error = error; |
| 190 | this.onError(date, error, execution); |
| 191 | } |
| 192 | |
| 193 | resolve(true); |
| 194 | }; |
| 195 | |
| 196 | // The jitter timer only earns its macrotask hop when a random delay is |
| 197 | // actually configured. With the default maxRandomDelay of 0 the delay |
| 198 | // is always 0, so run inline and fire on the heartbeat's own tick |
| 199 | // instead of bouncing through an extra setTimeout (which adds ~1ms+ of |
| 200 | // avoidable drift to every execution). |
| 201 | if (randomDelay > 0) { |
| 202 | setTimeout(execute, randomDelay); |
| 203 | } else { |
| 204 | execute(); |
| 205 | } |
| 206 | } else { |
| 207 | resolve(true); |
| 208 | } |
| 209 | }) |
| 210 | } |
| 211 | |
| 212 | const heartBeat = async () => { |
| 213 | // ignore milliseconds so the comparison against the matched slot is exact. |
nothing calls this directly
no test coverage detected