Skip to content

Commit ded480c

Browse files
committed
Adding the ability for the task queue to be cleared more programmatically via marker.
1 parent e5c003e commit ded480c

File tree

2 files changed

+92
-16
lines changed

2 files changed

+92
-16
lines changed

lib/util/task.js

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
// Task queue.
2121
this._queue = [];
2222
// Queue placeholder (for dealing with nested tasks).
23-
this._placeholder = {};
23+
this._placeholder = {placeholder: true};
24+
// Queue marker (for clearing the queue programatically).
25+
this._marker = {marker: true};
2426
// Options.
2527
this._options = {};
2628
// Is the queue running?
@@ -240,6 +242,19 @@
240242
return {task: task, nameArgs: name, args: args, flags: flags};
241243
};
242244

245+
// Append things to queue in the correct spot.
246+
Task.prototype._push = function(things) {
247+
// Get current placeholder index.
248+
var index = this._queue.indexOf(this._placeholder);
249+
if (index === -1) {
250+
// No placeholder, add task+args objects to end of queue.
251+
this._queue = this._queue.concat(things);
252+
} else {
253+
// Placeholder exists, add task+args objects just before placeholder.
254+
[].splice.apply(this._queue, [index, 0].concat(things));
255+
}
256+
};
257+
243258
// Enqueue a task.
244259
Task.prototype.run = function() {
245260
// Parse arguments into an array, returning an array of task+args objects.
@@ -250,15 +265,15 @@
250265
this._throwIfRunning(new TaskError('Task "' + fails[0].nameArgs + '" not found.'));
251266
return this;
252267
}
253-
// Get current placeholder index.
254-
var index = this._queue.indexOf(this._placeholder);
255-
if (index === -1) {
256-
// No placeholder, add task+args objects to end of queue.
257-
this._queue = this._queue.concat(things);
258-
} else {
259-
// Placeholder exists, add task+args objects just before placeholder.
260-
[].splice.apply(this._queue, [index, 0].concat(things));
261-
}
268+
// Append things to queue in the correct spot.
269+
this._push(things);
270+
// Make chainable!
271+
return this;
272+
};
273+
274+
// Add a marker to the queue to facilitate clearing it programatically.
275+
Task.prototype.mark = function() {
276+
this._push(this._marker);
262277
// Make chainable!
263278
return this;
264279
};
@@ -273,8 +288,10 @@
273288
var async = false;
274289
// Get next task+args object from queue.
275290
var thing;
276-
// Skip any placeholders.
277-
do { thing = this._queue.shift(); } while (thing === this._placeholder);
291+
// Skip any placeholders or markers.
292+
do {
293+
thing = this._queue.shift();
294+
} while (thing === this._placeholder || thing === this._marker);
278295
// If queue was empty, we're all done.
279296
if (!thing) {
280297
this._running = false;
@@ -340,9 +357,14 @@
340357
nextTask();
341358
};
342359

343-
// Clear all remaining tasks from the queue, or a subset.
344-
Task.prototype.clearQueue = function() {
345-
this._queue = [];
360+
// Clear remaining tasks from the queue.
361+
Task.prototype.clearQueue = function(options) {
362+
if (!options) { options = {}; }
363+
if (options.untilMarker) {
364+
this._queue.splice(0, this._queue.indexOf(this._marker) + 1);
365+
} else {
366+
this._queue = [];
367+
}
346368
// Make chainable!
347369
return this;
348370
};

test/util/task_test.js

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ exports['Tasks'] = {
285285
}
286286
});
287287
task.run('a:b:c').start();
288-
}, 'Task#clearQueue': function(test) {
288+
},
289+
'Task#clearQueue': function(test) {
289290
test.expect(1);
290291
var task = this.task;
291292
task.registerTask('a', 'Push task name onto result.', result.pushTaskname);
@@ -305,6 +306,59 @@ exports['Tasks'] = {
305306
});
306307
task.run('a b c d e').start();
307308
},
309+
'Task#mark': function(test) {
310+
// test.expect(1);
311+
var task = this.task;
312+
task.registerTask('a', 'Explode.', function() {
313+
throw task.taskError('whoops.');
314+
});
315+
task.registerTask('b', 'This task should never run.', result.pushTaskname);
316+
task.registerTask('c', 'This task should never run.', result.pushTaskname);
317+
318+
task.registerTask('d', 'Push task name onto result.', result.pushTaskname);
319+
task.registerTask('e', 'Explode.', function() {
320+
throw task.taskError('whoops.');
321+
});
322+
task.registerTask('f', 'This task should never run.', result.pushTaskname);
323+
324+
task.registerTask('g', 'Push task name onto result.', result.pushTaskname);
325+
task.registerTask('h', 'Push task name onto result.', result.pushTaskname);
326+
task.registerTask('i', 'Explode.', function() {
327+
throw task.taskError('whoops.');
328+
});
329+
330+
task.registerTask('j', 'Run a task and push task name onto result.', function() {
331+
task.run('k');
332+
result.push(this.name);
333+
});
334+
task.registerTask('k', 'Explode.', function() {
335+
throw task.taskError('whoops.');
336+
});
337+
task.registerTask('l', 'This task should never run.', result.pushTaskname);
338+
339+
task.registerTask('m', 'Push task name onto result.', result.pushTaskname);
340+
task.registerTask('n', 'Run a task and push task name onto result.', function() {
341+
task.run('o');
342+
result.push(this.name);
343+
});
344+
task.registerTask('o', 'Explode.', function() {
345+
throw task.taskError('whoops.');
346+
});
347+
348+
task.registerTask('p', 'Push task name onto result.', result.pushTaskname);
349+
350+
task.options({
351+
error: function(e) {
352+
result.push('!' + this.name);
353+
task.clearQueue({untilMarker: true});
354+
},
355+
done: function() {
356+
test.strictEqual(result.getJoined(), '!ad!egh!ij!kmn!op', 'The specified tasks should have run, in-order.');
357+
test.done();
358+
}
359+
});
360+
task.run('a b c').mark().run('d e f').mark().run('g h i').mark().run('j l').mark().run('m n').mark().run('p').mark().start();
361+
},
308362
'Task#requires': function(test) {
309363
test.expect(1);
310364
var task = this.task;

0 commit comments

Comments
 (0)