cron-scheduler
Advanced tools
Comparing version 1.0.0 to 1.2.0
@@ -0,1 +1,8 @@ | ||
## [v1.1.0] | ||
> Aug 10, 2017 | ||
- [#3] - Allow very long timeouts. ([@rgcjonas]) | ||
[v1.1.0]: https://github.com/rstacruz/cron-scheduler/compare/v1.0.0...v1.1.0 | ||
## [v1.0.0] | ||
@@ -7,1 +14,4 @@ > Jan 9, 2016 | ||
[v1.0.0]: https://github.com/rstacruz/cron-scheduler/tree/v1.0.0 | ||
[#3]: https://github.com/rstacruz/cron-scheduler/issues/3 | ||
[@rgcjonas]: https://github.com/rgcjonas | ||
39
index.js
@@ -1,5 +0,6 @@ | ||
var cronConverter = require('cron-converter') | ||
var CronConverter = require('cron-converter') | ||
var moment = require('moment-timezone') | ||
var ms = require('pretty-ms') | ||
var Promise = require('any-promise') | ||
var lt = require('long-timeout') | ||
var debug = function () {} | ||
@@ -11,3 +12,3 @@ | ||
var cron = function (options, fn) { | ||
function cron (options, fn) { | ||
var crontime, timezone, name, started, timer | ||
@@ -17,2 +18,6 @@ init() | ||
/* | ||
* Constructor. | ||
*/ | ||
function init () { | ||
@@ -27,3 +32,3 @@ if (!options || !options.on) { | ||
crontime = new cronConverter() | ||
crontime = new CronConverter() | ||
crontime.fromString(options.on) | ||
@@ -36,2 +41,6 @@ timezone = options.timezone | ||
/* | ||
* Sets a timer to run the next iteration. | ||
*/ | ||
function schedule () { | ||
@@ -44,6 +53,10 @@ var future = next() | ||
if (timer) clearTimeout(timer) | ||
timer = setTimeout(run, delta) | ||
if (timer) lt.clearTimeout(timer) | ||
timer = lt.setTimeout(run, delta) | ||
} | ||
/* | ||
* Returns the next scheduled iteration as a Moment date. | ||
*/ | ||
function next () { | ||
@@ -63,2 +76,6 @@ // get the time to check for. cron-converter needs an | ||
/* | ||
* Runs an iteration. | ||
*/ | ||
function run () { | ||
@@ -69,13 +86,17 @@ debug(name + ': starting') | ||
.then(function () { | ||
var elapsed = +new Date() - start | ||
debug(name + ': OK in ' + ms(elapsed)) | ||
debug(name + ': OK in ' + ms(elapsed())) | ||
if (started) schedule() | ||
}) | ||
.catch(function (err) { | ||
var elapsed = +new Date() - start | ||
debug(name + ': FAILED in ' + ms(elapsed)) | ||
debug(name + ': FAILED in ' + ms(elapsed())) | ||
throw err | ||
}) | ||
function elapsed () { return +new Date() - start } | ||
} | ||
/* | ||
* ...in the name of love. | ||
*/ | ||
function stop () { | ||
@@ -82,0 +103,0 @@ if (timer) { |
{ | ||
"name": "cron-scheduler", | ||
"description": "Runs jobs in periodic intervals", | ||
"version": "1.0.0", | ||
"version": "1.2.0", | ||
"author": "Rico Sta. Cruz <rico@ricostacruz.com>", | ||
@@ -12,2 +12,3 @@ "bugs": { | ||
"cron-converter": "0.0.8", | ||
"long-timeout": "^0.1.1", | ||
"moment-timezone": "0.5.0", | ||
@@ -17,2 +18,4 @@ "pretty-ms": "2.1.0" | ||
"devDependencies": { | ||
"sinon": "1.17.2", | ||
"sinon-in-sandbox": "1.0.0", | ||
"tape": "4.4.0" | ||
@@ -19,0 +22,0 @@ }, |
@@ -10,9 +10,10 @@ # cron-scheduler | ||
later, you should be fine. Otherwise, you'll also need to install | ||
[bluebird][], [rsvp][], [when][], or [q.js][]. | ||
[bluebird](https://github.com/petkaantonov/bluebird) (or [rsvp], [when], or [q.js]). | ||
[bluebird]: https://github.com/petkaantonov/bluebird | ||
[rsvp]: https://www.npmjs.com/package/rsvp | ||
[q]: https://github.com/kriskowal/q | ||
[q.js]: https://github.com/kriskowal/q | ||
[when]: https://github.com/cujojs/when | ||
[![Status](https://travis-ci.org/rstacruz/cron-scheduler.svg?branch=master)](https://travis-ci.org/rstacruz/cron-scheduler "See test builds") | ||
## cron() | ||
@@ -24,2 +25,4 @@ > `cron(options, function)` | ||
```js | ||
var cron = require('cron-scheduler') | ||
cron({ on: '0 9 * * *' }, function () { | ||
@@ -30,3 +33,4 @@ console.log('this will run every 9:00am') | ||
You can pass more options. | ||
#### Options | ||
The `options` parameter is an object with these things: | ||
@@ -49,5 +53,14 @@ - `on` *(String, required)* - the schedule in cron format (`min hour day | ||
#### Cron strings | ||
The `options.on` parameter is in cron standard format. Check the [cron | ||
cheatsheet](http://ricostacruz.com/cheatsheets/cron.html) for more details. | ||
Here are some examples: | ||
``` | ||
0 9 * * * - every 9:00AM | ||
0 12 * * 1 - every 12:00PM on mondays | ||
0 */2 * * * - every 2 hours | ||
``` | ||
#### Errors | ||
Any errors will be thrown, and will stop the scheduler. If this is not | ||
@@ -71,2 +84,3 @@ what you want, you may wish to decorate the function being passed. | ||
#### Promises | ||
If `function` returns a Promise, it will wait for it to finish before | ||
@@ -77,2 +91,3 @@ scheduling the next job. If the promise is rejected, it will be an unhandled | ||
#### Stopping | ||
To stop the cronjob, just run the `stop` method returned by `cron()`. | ||
@@ -85,3 +100,5 @@ | ||
#### Manually starting | ||
To manually invoke the cronjob, run the `run` method returned by `cron()`. | ||
This will not stop the next scheduled invocation. | ||
@@ -111,1 +128,13 @@ ```js | ||
[debug]: https://www.npmjs.com/package/debug | ||
## Thanks | ||
**cron-scheduler** © 2016+, Rico Sta. Cruz. Released under the [MIT] License.<br> | ||
Authored and maintained by Rico Sta. Cruz with help from contributors ([list][contributors]). | ||
> [ricostacruz.com](http://ricostacruz.com) · | ||
> GitHub [@rstacruz](https://github.com/rstacruz) · | ||
> Twitter [@rstacruz](https://twitter.com/rstacruz) | ||
[MIT]: http://mit-license.org/ | ||
[contributors]: http://github.com/rstacruz/cron-scheduler/contributors |
81
test.js
var test = require('tape') | ||
var cron = require('./index') | ||
var moment = require('moment-timezone') | ||
cron.debug(console.log.bind(console)) | ||
var sandbox = require('sinon-in-sandbox') | ||
test('cron', function (t) { | ||
var job = cron({ on: '0 9 * * *' }, function () {}) | ||
job.stop() | ||
t.end() | ||
sandbox(function (sinon, clock) { | ||
var clock = sinon.useFakeTimers() | ||
t.ok(+new Date() === 0, 'sinon timers is working') | ||
var cron = rerequire('./index') | ||
var job = cron({ on: '0 1 * * *', timezone: 'GMT' }, function () { | ||
t.pass('called') | ||
job.stop() | ||
t.end() | ||
}) | ||
clock.tick(3600 * 1000) | ||
}) | ||
}) | ||
test('cron with long delay', function (t) { | ||
sandbox(function (sinon, clock) { | ||
var clock = sinon.useFakeTimers() | ||
t.ok(+new Date() === 0, 'sinon timers is working') | ||
// HACK sinon timers do not implement the 2147483647ms limit, but we need it to make this test genuine | ||
var oldSetTimeout = setTimeout | ||
setTimeout = function(func, timeout) { | ||
if (timeout < 1 || timeout > 2147483647) timeout = 1 | ||
return oldSetTimeout(func, timeout) | ||
} | ||
var cron = rerequire('./index') | ||
// we architect it in a way to have about three months until the next execution | ||
var called = false | ||
var job = cron({ on: '0 1 31 3 *', timezone: 'GMT' }, function () { | ||
t.fail('called') | ||
called = true | ||
}) | ||
clock.tick(3600 * 1000) | ||
if (!called) t.pass('not called') | ||
job.stop() | ||
t.end() | ||
}) | ||
}) | ||
test('cron timezones', function (t) { | ||
sandbox(function (sinon) { | ||
var clock = sinon.useFakeTimers() | ||
var cron = rerequire('./index') | ||
// Asia/Manila is +0800 GMT, so this is 1AM GMT | ||
var job = cron({ on: '0 9 * * *', timezone: 'Asia/Manila' }, function () { | ||
t.pass('called') | ||
job.stop() | ||
t.end() | ||
}) | ||
clock.tick(3600 * 1000) | ||
}) | ||
}) | ||
/* | ||
* substitute for require() that will not cache its result, so it make be | ||
* re-required again in the future. we need this so that cron/moment will | ||
* pick up the sandboxed Date object. | ||
*/ | ||
function rerequire (mod) { | ||
var keys = Object.keys(require.cache) | ||
var result = require(mod) | ||
Object.keys(require.cache).forEach(function (key) { | ||
if (keys.indexOf(key) === -1) delete require.cache[key] | ||
}) | ||
return result | ||
} |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
9234
7
155
133
5
3
1
+ Addedlong-timeout@^0.1.1
+ Addedlong-timeout@0.1.1(transitive)