Skip to content

Commit e96dcdb

Browse files
committed
Workflow Behavior Change: Sub-job queuing now considers each workflow job to be its own queue "namespace". Fixes #218.
1 parent 9e94e45 commit e96dcdb

1 file changed

Lines changed: 26 additions & 21 deletions

File tree

lib/job.js

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,12 @@ class Jobs {
264264
self.monitorJob(job);
265265

266266
if (job.state == 'queued') {
267-
var queue_id = job.event;
268-
if (job.workflow && job.workflow.node && (job.type == 'adhoc')) queue_id += '-' + job.workflow.node;
267+
// build up a job queue id using same logic as findSimilarJobs
268+
var parts = [ job.event ];
269+
if (job.workflow && job.workflow.node) parts = [ job.workflow.node ]; // replace event
270+
if (job.workflow && job.workflow.job) parts.push( job.workflow.job );
271+
if (job.type) parts.push( job.type );
272+
var queue_id = parts.join('-');
269273

270274
if (!queues[queue_id]) queues[queue_id] = [];
271275
queues[queue_id].push(job);
@@ -275,25 +279,14 @@ class Jobs {
275279
// check queues for available slots
276280
for (var queue_id in queues) {
277281
var queued = queues[queue_id];
278-
// var event = Tools.findObject( this.events, { id: event_id } );
279-
// if (!event) continue; // sanity
280282

281-
var criteria = { state: 'active' };
282-
if (queue_id.match(/^(\w+)\-(\w+)$/)) {
283-
// support adhoc workflow jobs (where the event is the WF event)
284-
var event_id = RegExp.$1;
285-
var node_id = RegExp.$2;
286-
criteria['event'] = event_id;
287-
criteria['workflow.node'] = node_id;
288-
}
289-
else {
290-
criteria['event'] = queue_id;
291-
}
292-
293-
// use limit definition from first queued job (honor system)
283+
// use limit definition from first queued job
284+
// (it SHOULD match the rest of the jobs in the queue group)
294285
var job = queued[0];
295286
var job_limit = Tools.findObject( job.limits || [], { type: 'job', enabled: true } );
296-
var jobs = this.findActiveJobsDeep(criteria);
287+
var jobs = this.findSimilarJobs(job, { state: 'active' }).concat(
288+
this.findSimilarJobs(job, { state: 'starting' })
289+
);
297290

298291
if (job_limit && (jobs.length < job_limit.amount)) {
299292
// we have room! launch queued job waiting the longest
@@ -318,7 +311,8 @@ class Jobs {
318311
this.masterSync();
319312
}
320313

321-
// FUTURE NOTE: This will only launch a max of 1 queued job per event per second (per tick)
314+
// FUTURE NOTE: This will only launch a max of 1 queued job per group per second (per tick)
315+
// However, monitorJobs is also called when jobs complete, so that compensates
322316
}
323317
} // foreach queue
324318
}
@@ -444,8 +438,19 @@ class Jobs {
444438
// find jobs with criteria and same event, OR same wf+node if adhoc
445439
criteria['event'] = job.event;
446440

447-
if (job.workflow && job.workflow.node && (job.type == 'adhoc')) {
441+
// include job type if applicable
442+
if (job.type) criteria['type'] = job.type;
443+
444+
// for wf nodes use the node id as criteria (replace event)
445+
if (job.workflow && job.workflow.node) {
448446
criteria['workflow.node'] = job.workflow.node;
447+
delete criteria['event'];
448+
}
449+
450+
// if running inside a workflow, include the parent workflow job id itself as criteria,
451+
// so that limits are applied in a "single workflow execution run scope" (see gh issue # 218)
452+
if (job.workflow && job.workflow.job) {
453+
criteria['workflow.job'] = job.workflow.job;
449454
}
450455

451456
return Tools.findObjectsDeep( Object.values(this.activeJobs), criteria );
@@ -890,7 +895,7 @@ class Jobs {
890895
var queue_limit = Tools.findObject( job.limits, { type: 'queue', enabled: true } );
891896

892897
if (queue_limit && queue_limit.amount) {
893-
var queued = this.findActiveJobs({ event: job.event, state: 'queued' });
898+
var queued = this.findSimilarJobs(job, { state: 'queued' });
894899

895900
if (queued.length < queue_limit.amount) {
896901
// room in queue, yay!

0 commit comments

Comments
 (0)