Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:

class Job {
    constructor(type, id, params, reporter) {
        this.type = type;
        this.id = id;
        this.params = params;
        this.reporter = reporter;
        this.state = {};

        this.progress = {
            numerator: 0,
            denominator: 1,
        }
        this.progressTimeout = null;
        this.lastReportingTime = null;
    }

    // Returns a promise
    jobPromise() {
        return new Promise((resolve, reject) => {
            reject(new Error('You must implement the jobPromise method which returns a promise to execute for this job!'));
        })
    }

    assertJobType(type) {
        if (type !== this.type) {
            throw new Error('Invalid assertion');
        }
    }

    getInitialState() {
        return {};
    }

    validateParams() {
        // Implement to validate the params here
    }

    setState(changes) {
        Object.assign(this.state, changes);
        this.reporter.state(this.state);
    }

    executeJob() {
        return Promise.resolve().then(() => {
            let initial = this.getInitialState();
            if (Object.keys(initial).length > 0) {
                this.setState(initial);
            }

            this.validateParams();

            return this.jobPromise();
        });
    }

    log(logData) {
        this.reporter.addLog(logData);
    }

    queueChildJob(queueId, jobType, jobParams) {
        return this.reporter.queueChildJob(queueId, jobType, jobParams);
    }

    getChildJob(jobId) {
        return this.reporter.getChildJob(jobId);
    }

    waitForJob(jobId) {
        return new Promise((resolve, reject) => {
            this.log('Waiting for job to complete: ' + jobId);
            let i = setInterval(() => {
                this.log('Waiting for job to complete: ' + jobId);
                let job = this.getChildJob(jobId);
                if (job === null) {
                    clearInterval(i);
                    reject(new Error('Cannot find job: ' + jobId));
                } else {
                    if (job.status === 3 || job.status === 4) {
                        clearInterval(i);
                        resolve(job);
                    }
                }
            }, 5000);
        })
    }

    setProgressLevel(progressNumerator, progressDenominator) {
        this.progress = {
            numerator: progressNumerator,
            denominator: progressDenominator,
        }

        // Progress levels are not guaranteed to get instantly sent back to the queue
        // A job might be running this many times so we need a debouncer of about 5 seconds
        // This could mean that some of the progress values which are set in the job, actually get ignored due to process death.
        // The progress is only applicable during status = RUNNING so can be ignored otherwise. Finished status implies 100% complete.
        // This value is for showing a nice progress graphic to show how much of the job has completed.
        // A log event and state update event are not fired.  The values are simply updated direct in the key "progress".
        let debounceSeconds = 3;
        let now = (new Date()).getTime();
        let debounceTime = debounceSeconds * 1000;

        if (this.progressTimeout === null) {
            if (this.lastReportingTime === null) {
                debounceTime = 1;
            } else {
                if ((now - this.lastReportingTime) > (debounceSeconds * 1000)) {
                    debounceTime = 1;
                }
            }
        } else {
            // There is an old interval waiting
            clearInterval(this.progressTimeout);
        }

        this.progressTimeout = setTimeout(() => {
            this.lastReportingTime = (new Date()).getTime();
            this.reporter.progress(this.progress);
        }, debounceTime);
    }
}

module.exports = Job;