Skip to content

Instantly share code, notes, and snippets.

@andresmatasuarez
Last active November 24, 2016 15:19
Show Gist options
  • Save andresmatasuarez/34ff17f63affe05e77a3 to your computer and use it in GitHub Desktop.
Save andresmatasuarez/34ff17f63affe05e77a3 to your computer and use it in GitHub Desktop.
NodeJS | Module: Repeat | Offers an abstraction for a repeatable task execution, wrapping it up in a startable and stoppable object.
/**
* @module Repeat
* @desc Offers an abstraction for a repeatable task execution, wrapping it up in a startable and stoppable object.
* @see {@link https://gist.github.com/andresmatasuarez/34ff17f63affe05e77a3| GitHub gist}
* @author Andrés Mata Suárez <amatasuarez@gmail>
* @license {@link http://www.opensource.org/licenses/mit-license.php| MIT License}
*
* @requires {@link https://github.com/petkaantonov/bluebird| bluebird}
* @requires {@link https://gist.github.com/andresmatasuarez/66edcd9710986cca4c59| Log}
*
* @example
* var Repeat = require('./repeat');
*
* var task = function(){
* return promiseAction(...);
* };
*
* var repeatable = new Repeat('My task', task, 5000);
*
* // Start task
* repeatable.start();
*
* // Stop task
* repeatable.stop();
*/
'use strict';
var CancellationError = require('bluebird').CancellationError;
var Log = require('./log');
function _repeat(taskName, task, delay){
return task()
.cancellable()
.then(function(){
Log.Repeat.waiting(delay, taskName);
})
.delay(delay)
.then(function(){
Log.Repeat.repeat(taskName);
return _repeat(taskName, task, delay);
})
.catch(CancellationError, function(){
Log.Repeat.stop(taskName);
});
}
/**
* @constructor
*
* @param {string} taskName - Name that identifies this task.
* @param {function} task - Task to be repeated (as a function returning a Bluebird promise).
* @param {number} delay - Delay before repetition after task completion.
*
*/
function Repeat(taskName, task, delay){
this.taskName = taskName;
this.task = task;
this.delay = delay;
this.firstExecution = true;
}
/**
* Starts execution of task.
*/
Repeat.prototype.start = function(){
if (this.runningTask){
Log.Repeat.alreadyStarted(this.taskName);
return;
}
Log.Repeat.start(this.taskName);
this.firstExecution = false;
this.runningTask = _repeat(this.taskName, this.task, this.delay);
};
/**
* Stops execution of task.
*/
Repeat.prototype.stop = function(){
if (!this.runningTask){
Log.Repeat.alreadyStopped(this.taskName);
return;
}
Log.Repeat.stop(this.taskName);
this.runningTask.cancel();
this.firstExecution = true;
delete this.runningTask;
};
/**
* Static method to fire a repeatable task and forget about it, leaving it running indefinitely.
*/
Repeat.fireAndForget = function(taskName, task, delay){
new Repeat(taskName, task, delay).start();
};
module.exports = Repeat;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment