-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcapataz_node.js
2 lines (2 loc) · 4.18 KB
/
capataz_node.js
1
2
//! capataz 0.1.0
"use strict";var basis=require("./static/basis");exports.Capataz=basis.declare({constructor:function(a){basis.initialize(this,a).integer("workerCount",{defaultValue:2,coerce:!0}).number("maxRetries",{defaultValue:50,coerce:!0}).integer("minDelay",{defaultValue:100,coerce:!0}).number("maxDelay",{defaultValue:12e4,coerce:!0}).number("maxScheduled",{defaultValue:5e3,coerce:!0}).number("desiredEvaluationTime",{defaultValue:5e3,coerce:!0}).number("maxTaskSize",{defaultValue:50,coerce:!0}).object("statistics",{defaultValue:new basis.Statistics}).object("logger",{defaultValue:basis.Logger.ROOT}).object("jobs",{defaultValue:{}}),this.__pending__=[],this.__jobCount__=0,this.__startTime__=Date.now()},wrappedJob:function(a,b,c){return"(function(){return basis.Future.imports.apply(this,"+JSON.stringify(a||[])+").then(function(deps){return ("+b+").apply(this,deps.concat("+JSON.stringify(c||[])+"));});})()"},schedule:function(a){var b=new basis.Future;if(this.scheduledJobsCount()>=this.maxScheduled)b.reject(new Error("Cannot schedule more jobs: the maximum amount ("+this.maxScheduled+") has been reached."));else{var c={id:(this.__jobCount__=4294967295&++this.__jobCount__).toString(36),info:""+a.info,code:this.wrappedJob(a.imports,a.fun,a.args),future:b,scheduledSince:Date.now(),assignedSince:-1/0};this.jobs[c.id]=c,this.statistics.add({key:"scheduled"})}return b},scheduledJobsCount:function(){return Object.keys(this.jobs).length},nextTask:function(a){a=isNaN(a)?Math.round(Math.max(1,Math.min(this.maxTaskSize,this.desiredEvaluationTime/Math.max(1,this.statistics.average({key:"evaluation_time",status:"resolved"}))))):0|+a,this.__pending__.length<1&&(this.__pending__=Object.keys(this.jobs));var b=this.__pending__.splice(0,a),c=this;return this.statistics.add({key:"task_size"},b.length),{serverStartTime:this.__startTime__,jobs:basis.iterable(b).map(function(a){var b=c.jobs[a];return b&&{id:a,info:b.info,code:b.code,assignedSince:Date.now()}}).filter().toArray()}},processResult:function(a){var b,c=a.id,d=this.jobs[c];delete this.jobs[c],d?isNaN(a.assignedSince)||a.assignedSince<this.__startTime__||a.assignedSince>Date.now()||a.time<=0?(this.logger.warn("Posted result for ",c," is not valid. Ignoring POST."),this.jobs[c]=d,b="invalid"):"undefined"!=typeof a.error?(b="rejected",d.future.reject(a.error)):(b="resolved",d.future.resolve(a.result)):(this.logger.debug("Job ",a.id," not found. Ignoring POST."),b="ignored"),this.statistics.add({key:"evaluation_time",status:b,platform:a.clientPlatform,client:a.postedFrom},a.time),this.statistics.add({key:"roundtrip_time",status:b,platform:a.clientPlatform,client:a.postedFrom},Date.now()-a.assignedSince)},get_config:function(a,b){b.set("Cache-Control","max-age=0,no-cache,no-store"),b.json({workerCount:this.workerCount,maxRetries:this.maxRetries,minDelay:this.minDelay,maxDelay:this.maxDelay})},get_job:function(a,b){var c=this.nextTask();return c.jobs.length>0?(b.set("Cache-Control","max-age=0,no-cache,no-store"),b.json(c),this.statistics.add({key:"jobs_per_serving"},c.jobs.length)):(this.logger.debug("There are no pending jobs yet."),b.send(404,"There are no pending jobs yet. Please try again later.")),!0},post_job:function(a,b){var c=this,d=a.connection.remoteAddress+"";a.body&&Array.isArray(a.body.jobs)?(b.send("Thank you."),a.body.jobs.forEach(function(a){a.postedFrom=d,c.processResult(a)})):b.send(400,"Invalid post.")},get_stats:function(a,b){b.set("Cache-Control","max-age=0,no-cache,no-store"),b.json(this.statistics)},configureApp:function(a){var b=require("express"),c=a.app||b();return c.use(b.compress()),c.use(b.bodyParser()),a.staticPath&&c.use(b.static(a.staticPath)),c.get(a.jobPath||"/job",this.get_job.bind(this)),c.post(a.jobPath||"/job",this.post_job.bind(this)),c.get(a.statsPath||"/stats",this.get_stats.bind(this)),c.get(a.configPath||"/config",this.get_config.bind(this)),a.logFile&&this.logger.appendToFile(a.logFile),c},scheduleAll:function(a,b,c){var d=basis.iterable(a).__iter__(),b=isNaN(b)?this.maxScheduled:Math.min(0|+b,this.maxScheduled),e=this;return basis.Future.doWhile(function(){var a,f=[];try{for(var g=0;b>g;g++)a=e.schedule(d()),f.push(a),c&&c(a)}catch(h){basis.Iterable.prototype.catchStop(h)}return f.length<1?!1:basis.Future.all(f)})}});