Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework on the previous version spec. #21

Open
yuanyan opened this issue Jan 19, 2014 · 0 comments
Open

Rework on the previous version spec. #21

yuanyan opened this issue Jan 19, 2014 · 0 comments

Comments

@yuanyan
Copy link

yuanyan commented Jan 19, 2014

Current spec is more simple, some work on previous version:

var Promise = require('es6-promise').Promise;
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var _ = require('lodash');

var Status = {
    PENDING:  0, // Indicates that the task has not been executed yet.
    RUNNING:  1, // Indicates that the task is running.
    REJECTED: 2, // Indicates that the task has completed without errors.
    RESOLVED: 3, // Indicates that the task not completed.
    FINISHED: 4, // Indicates that the task has finished.
    FAULTED: 5   // Indicates that the task finished due to an unhandled exception.
};

function Task (config) {
    if (!(this instanceof Task)) return new Task(config);
    this.setOptions(config.options);
    this._status = Status.PENDING;
    _.extend(this, config);
    EventEmitter.call(this);
}

util.inherits(Task, EventEmitter);

Task.Status = Status;


/**
 * Task name must be a combination of one or more digits, letters a–z, underscores, and/or dashes,
 * satisfying the following regular expression: [0-9a-zA-Z\-\_]+
 * @type {String}
 */
Task.prototype.name = null;
Task.prototype.timeout = null;
Task.prototype.force = false;
Task.prototype.options = {};

Task.prototype._parseOptions = function (options) {
    var defaults = _.merge({}, this.options, options, function(d, o) {
        return o.defaultValue || o;
    });
    return _.extend(defaults, this._options || {});
};

Task.prototype.getOptions = function(){
    return this._options;
};

Task.prototype.setOptions = function(options){
    return this._options = this._parseOptions(options);
}

Task.prototype.getStatus = function(){
    return this._status;
};

Task.prototype.getInput = function(){
    return this._input;
};

Task.prototype.setTimeout = function(msecs, callback) {
    if (msecs > 0 && !isNaN(msecs) && isFinite(msecs)) {
        this.timeout = msecs;
        if (callback) {
            this.on('timeout', callback);
            this._timeoutHandler = callback;
        }
    } else if (msecs === 0) {
        this.clearTimeout(callback);
    }
};

Task.prototype.clearTimeout = function(callback){
    this.timeout = null;
    if (this._timer) {
        clearTimeout(this._timer);
    }
    callback = callback || this._timeoutHandler;
    if (callback) {
        this.removeListener('timeout', callback);
    }
};

/**
 * Main entry point for task.
 * @param input
 * @returns {*}
 */
Task.prototype.run = function (input) {
    this._input = !_.isArray(input)? [input]: input;
    return this._run();

};

Task.prototype._run = function(resolve, reject){
    var self = this;
    if(this.timeout){
        this._timer = setTimeout(function(){
            self.emit('timeout');
        }, this.timeout)
    }
    var promise = Promise.resolve();
    return promise.then(this._setup.bind(self))
        .then(this._execute.bind(self))
        .then(this._teardown.bind(self))
        .catch(this._error.bind(self));
}

/**
 * Thenable
 */
Task.prototype.then = function(resolve, reject){
    return this._run(resolve, reject);
};

Task.prototype._setup = function () {
    var self = this;
    return new Promise(function (resolve, reject) {
        self.emit('setup');
        self.setup(resolve, reject);
    });
};

Task.prototype._execute = function(){
    var self = this;
    return new Promise(function (resolve, reject) {
        self.emit('execute');
        self._status = Status.RUNNING;
        self.execute(function(){
            self._status = Status.RESOLVED;
            resolve.apply(self, arguments);
        }, function(){
            self._status = Status.REJECTED;
            reject.apply(self. arguments);
        });
    });
};

Task.prototype._teardown = function(res){
    this.emit('teardown');
    this._status = Status.FINISHED;
    return Promise.resolve(this.teardown(res));
};

Task.prototype._error = function(err){
    this._status = Status.FAULTED;
    this.emit('error', err);
    return this.error(err);
}

/*
When an task is run, the task goes through 3 steps:
1. setup(Params...), invoked before the task is executed. This step is normally used to setup the task.
2. execute(Params...), invoked immediately after setup() finishes executing.
   This step is used to perform task that can take a long time.The parameters of the task are passed to this step.
   The result of the task must be returned by this step and will be passed back to the last step.
3. teardown(Result), invoked after execute() finishes. The result of the execute() is passed to this step as a parameter.
*/

Task.prototype.setup = function (resolve, reject) {
    resolve();
};

Task.prototype.execute = function (resolve, reject) {
    // var input = this.getInput();
    // input.isStream();
};

Task.prototype.teardown = function (res) {
    return res;
};

Task.prototype.error = function (err) {
    return err;
};

module.exports = Task;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant