schedule icon indicating copy to clipboard operation
schedule copied to clipboard

build(schedule): replace dependency cron with croner

Open Hexagon opened this issue 2 years ago • 11 comments

PR Checklist

Please check if your PR fulfills the following requirements:

  • [X] The commit message follows our guidelines: https://github.com/nestjs/nest/blob/master/CONTRIBUTING.md
  • [X] Tests for the changes have been added (for bug fixes / features)
  • [X] Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • [X] Bugfix
  • [X] Feature
  • [X] Build related changes

What is the current behavior?

Issue Number: #1164

What is the new behavior?

This PR replaces dependency cron with croner.

Croner

  • is ready for the future, supporting Node, Deno, Bun and Browser environments.
  • supports both ESM and CJS.
  • has more predictive behaviour and less bugs. (not affected by #454 as an example)
  • partial solution for #9654 - "Provide alternatives to scheduling with node-cron" which is closed but not fully resolved.
  • uses the same pattern as vixie cron (see #1159)
  • has no dependencies (see #1147)

Changes and new features brought by this PR

  • Now uses standard syntax for specifying months. Previously, it expected months to be represented as 0-11, but now it expects the "standard" 1-12 format like Vixie-cron, crontab.guru, etc.
  • Supports using L in the pattern to indicate the last day of the month or the last weekday of the month.
  • Supports nth weekday of month, including last weekday of month. Example: 5#L is last friday of current month.
  • Adds an option legacyMode: Which adds support for using an alternative way of combining the day of the week and day of the month - to be able to find, for example, Friday the 13th. More information on this feature is available in croner issue #53.
  • Adds an option context: that allows the user to pass a context (object) to the triggered function.
  • Adds an option overrunProtection: that allows the user to block executions that would overlap the previous execution.
  • Adds an option maxRuns: to specify the maximum number of executions before stopping the job.
  • Adds an option interval: to specify the minimum number of seconds between triggers, regardless of how the pattern looks.
  • Removes the dependency on Luxon, making the package much smaller.

Does this PR introduce a breaking change?

  • [X] Yes
  • Type for option utcOffset changes from string | number to number
  • Code will now throw if trying to combine utcOffset with timezone, as this combination does not make sense.
  • Croner methods .previousRun(), .nextRun() and .nextRuns() return native JavaScript Date objects instead of moment-objects.
  • Job instances of cron and croner differ in exported members. Documentation need to be updated
    
    stop() - stops a job that is scheduled to run.
    start() - restarts a job that has been stopped.
    setTime(time: CronTime) - stops a job, sets a new time for it, and then starts it
    lastDate() - returns a string representation of the last date a job executed
    nextDates(count: number) - returns an array (size count) of moment objects representing upcoming job execution dates.
    HINT
    Use toDate() on moment objects to render them in human readable form.
    
    Should be changed to something like
    stop() - stops a job permanently and clears the internal timeOut, allowing the process to exit.
    pause() - pause a job that is scheduled to run.
    resume() - resumes a job that has been paused.
    currentRun() - returns a date object representing the date of the current run, this is updated before execution
    previousRun() - returns a date object representing the date of the previous run, this is updated after execution
    nextRuns(count: number) - returns an array (size count) of moment objects representing upcoming job execution dates.
    nextRun() - returns a Date object representing time of upcoming job execution.
    isStopped() - returns a boolean showing if the job is permanently stopped
    isRunning() - returns a boolean showing if the job is scheduled to run
    isBusy() - returns a boolean showing if the job is currently busy running a task 
    getPatter() - returns the original pattern
    HINT
    Use toLocaleString() on Date objects to render them in human readable form.
    
  • (because of above, some of the examples in the documentation need to be updated)
  • Will now support modifier L in pattern, needs to be added in documentation. From the croner documentation
    • L: L can be used in the day of the month field to specify the last day of the month. It can also be used in the day of the week field to specify the last specific weekday of the month, for example, the last Friday (`5#L`).
  • Adds new options, as mentioned earlier.

Other information

Hexagon avatar Feb 12 '23 23:02 Hexagon