jakejs / jake

JavaScript build tool, similar to Make or Rake. Built to work with Node.js.
http://jakejs.com
Apache License 2.0
1.97k stars 190 forks source link

Invoking synchronous task doesn't finish all prereqs #269

Open veldsla opened 10 years ago

veldsla commented 10 years ago

Hi,

I encountered an issue when I invoke a task with multiple prerequisites. If you take the following jakefile:

var sleep = require("sleep").sleep;
task("waitsyncA", function() {
    console.log("sleep A");
    sleep(1);
    console.log("wake A");
});
task("waitsyncB", function() {
    console.log("sleep B");
    sleep(1);
    console.log("wake B");
});
task("waitsyncC", function() {
    console.log("sleep C");
    sleep(1);
    console.log("wake C");
});
task("waitsyncD", ["waitsyncA", "waitsyncB", "waitsyncC"]);
desc("do invoke");
task("doInvoke", function() {
    jake.Task["waitsyncD"].invoke();
    console.log("as invoke prereqs done?");

});
desc("do as prereq");
task("doPrereq", ["waitsyncD"], function() {
    console.log("as prereqs done?");
});

I use the sleep modules to create synchronous tasks that take some time. The task doPrereq runs fine, but the doInvoke task however prematurely finishes the D task. I dug a little more in the source and think it may be related to the fact that you call the next prereq in an asyncronous way (https://github.com/jakejs/jake/blob/master/lib/task/task.js#L224). I'm not sure why you do this.

Also this code is not used when parallel prerequisites are used. I made a few changes that let all prerequisites run through the async loop (asyncLimit or asyncSeries when in non-parallel compatibility mode and the order needs to be guaranteed). This avoids the code duplications (which kinda bothered me) by removing nextPrereq and handlePrereqComplete and saves about 50 LOC. Both cases run as expected (as does the entire testsuite). I can make a pull request if you like.

mde commented 10 years ago

I'm not familiar with the sleep module or how it works, but I can't imagine it provides a real, synchronous 'sleep.' The reason the prereqs are called asychronously is because an asyncronous API can accommodate both a sync and async calling pattern (but not the other way around).

veldsla commented 10 years ago

I encountered the issue with tasks that used synchronous methods from the shelljs module. I recreated the testcase using sleep. If you replace sleep call with a giant for loop it still fails