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

async task not calling 'complete' #271

Closed raeesaa closed 9 years ago

raeesaa commented 9 years ago

Hi,

I have defined an async task in Jakefile as:

task('save', {async: true}, function () {
    var funders = someFunction();

    MongoClient.connect(config.development.dbUrl, function(err, db) {
      if (!err) {
        db.collection("somecollection").insert({date: new Date(), funders: funders}, function(err, doc) {
          if(err)
            console.log(err);

          console.log('Data inserted');
          complete();
        });
      }
    });
  });

Task get executed fine and I can see 'Data inserted' logged into the console. But complete() is not getting called due to some reason. I am stuck with this task since past four hours. Any idea why complete is not getting invoked?

mde commented 9 years ago

Could you provide a little more context here? How are you ascertaining that complete isn't being called?

raeesaa commented 9 years ago

I can say that because 'Data inserted' gets logged into the console but console hangs there. I need to press ctrl + C to come out of the task which is not the case for other synchronous tasks.

Can nested callbacks be the reason for complete() not being called or am I doing something wrong?

funders_save

mtimofiiv commented 9 years ago

I have the exact same issue, also with modifying a mongo record.

Like @raeesaa, the task executes fine but then the process does not exit. Here's my Jakefile: https://gist.github.com/mtimofiiv/33a521b5b7c9f301d047

mtimofiiv commented 9 years ago

I think I fixed this for myself - there's a bit right in the docs about it. Tasks marked as { async: true }, including ones that are not inherently marked as so but make use of something like promises/callbacks (as in the case of my tasks that run an asynchronous Mongo query) just need this event listener somewhere in the Jakefile:

jake.addListener('complete', function () {
  process.exit();
});

source: http://jakejs.com/docs#tasks_cleanup_after_all_tasks_run,_jake_'complete'_event

mde commented 9 years ago

Glad you were able to get this sorted out. :) @raeesaa, is this still an issue for you?

siimsoni commented 9 years ago

It seems like it is a common error that tasks don't get terminated. I highly recommend to rethink this part of Jake or to come up with some guide how to resolve these issues… I'm even having issues to the extent that everything runs fine, but hangs at the end. I can run one task, and it will hang. I can run multiple tasks, and all of the tasks will run, but it will hang at the end. I can remove all the code from the tasks. At the end I understand the only active processes are stdout and stderr… I am at a cafe now, and it doesn't work, but it worked when I left home one hour earlier. I'm not very proficient with Node, but I can say I am very confused now. I can't use process.exit(), because sometimes I need to run one task, sometimes I need to invoke multiple tasks.

mde commented 9 years ago

This is not a Jake problem, it's a problem in your application code or a third-party library. If you open connections and don't close them, or call out to libraries that don't clean up after themselves, the Node process will continue running. Jake has already exited.

Jake does itself give you a 'complete' event you can listen for that tells you when all tasks have finished running:

http://jakejs.com/docs#tasks_cleanup_after_all_tasks_run,_jake_%27complete%27_event