feat(cron): better API (#40)

This commit is contained in:
Julien Fontanet 2018-02-06 10:20:11 +01:00 committed by GitHub
parent 179aadafa4
commit be3b684866
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 37 deletions

View File

@ -13,17 +13,20 @@ Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/cron)
## Usage ## Usage
```js ```js
import * as Cron from '@xen-orchestra/cron' import { createSchedule } from '@xen-orchestra/cron'
Cron.parse('* * * jan,mar *') const schedule = createSchedule('0 0 * * sun', 'America/New_York')
// → { month: [ 1, 3 ] }
Cron.next('* * * jan,mar *', 2, 'America/New_York') schedule.next(2)
// → [ 2018-01-19T22:15:00.000Z, 2018-01-19T22:16:00.000Z ] // [ 2018-02-11T05:00:00.000Z, 2018-02-18T05:00:00.000Z ]
const stop = Cron.schedule('@hourly', () => { const job = schedule.createJob(() => {
console.log(new Date()) console.log(new Date())
}, 'UTC+05:30') })
job.start()
job.stop()
``` ```
### Pattern syntax ### Pattern syntax

View File

@ -1,40 +1,49 @@
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import nextDate from './next' import next from './next'
import parse from './parse' import parse from './parse'
const autoParse = pattern => class Job {
typeof pattern === 'string' ? parse(pattern) : schedule constructor (schedule, fn) {
const wrapper = scheduledRun => {
export const next = (cronPattern, n = 1, zone = 'utc') => { if (scheduledRun) {
const schedule = autoParse(cronPattern) fn()
}
let date = DateTime.fromObject({ zone }) this._timeout = setTimeout(wrapper, schedule.next() - Date.now(), true)
const dates = [] }
for (let i = 0; i < n; ++i) { this._fn = wrapper
dates.push((date = nextDate(schedule, date)).toJSDate()) this._timeout = undefined
}
return dates
}
export { parse }
export const schedule = (cronPattern, fn, zone = 'utc') => {
const wrapper = () => {
fn()
scheduleNextRun()
} }
let handle start () {
const schedule = autoParse(cronPattern) this.stop()
const scheduleNextRun = () => { this._fn()
const now = DateTime.fromObject({ zone })
const nextRun = next(schedule, now)
handle = setTimeout(wrapper, nextRun - now)
} }
scheduleNextRun() stop () {
return () => { clearTimeout(this._timeout)
clearTimeout(handle)
} }
} }
class Schedule {
constructor (pattern, zone = 'utc') {
this._schedule = parse(pattern)
this._dateTimeOpts = { zone }
}
createJob (fn) {
return new Job(this, fn)
}
next (n) {
const dates = new Array(n)
const schedule = this._schedule
let date = DateTime.fromObject(this._dateTimeOpts)
for (let i = 0; i < n; ++i) {
dates[i] = (date = next(schedule, date)).toJSDate()
}
return dates
}
}
export const createSchedule = (...args) => new Schedule(...args)