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

Jake silently stops when depending on a "file" task #272

Open SIGSEGV111 opened 9 years ago

SIGSEGV111 commented 9 years ago

Hi,

I am trying to port an existing project to over Jake. Initially everything worked fine until I hit a problem with the file tasks. When one of my tasks depend on a file task, and the file for the file-task already exists, Jake silently stops. No console output at all, no error message, no tasks get executed. Simply nothing happens - although Jakes takes a few seconds to work.

I then strace'd jake: It stat()'s all my source files (as it should), then apparently sees that there is no need to rebuild my "library.css" file (also correct, the file is up-to-date), and then simply stops working - skipping all other downstream tasks (this is not correct in my opinion :-) ).

I tried switching async on/off, or using different parallelWorker value. All my tasks get the following parameters: var task_parameters = {async:true, parallelLimit:16};

After all this I added a dummy tasks, without dependencies, and also added this task to the list of dependencies - the same list where also the file task is listed. If I use a parallelWorker value of 3 or more, it actually executes the dummy task, but only the dummy task -nothing else.

Any ideas what could cause this?

Thanks & Regards Simon

mde commented 9 years ago

This is mysterious. The parallel task stuff was a pretty significant change, so I of course suspect those changes could be the source of your problem. It might be worth seeing if you have this same problem in version 0.7 (the previous version). Could you try installing that version and seeing what happens?

SIGSEGV111 commented 9 years ago

HI,

Thanks for your reply. Following your advise, I did the following:

1) cd "workspace-folder" 2) npm install jake@0.7.20 3) ./node_modules/.bin/jake

As output I received:

jake aborted. Maximum call stack size exceeded

I traced this down to the file task. When I remove the file tasks from the dependency tree, jake executes normally.

Then I tried if it would work, if I only create the file task and the default task, but even that failed with the same error. Next I removed all dependencies from the file task, and this actually worked out. While this is of course not very useful, it at least narrowes it down to a problem with the dependencies of the file task. The dependencies are only other files.from my project.

Do I have to do anything special here? Maybe I somehow miss-use the API?

I create the "file" task as follows: file("library.css", [all css filenames in my project as array of strings], {async:true, parallelLimit:16}, function() { .... this.complete(); .... });

Some other task then simply include "library.css" in their list of dependencies.

I suspect that version 8.0.9 fails because of a similiar reason, yet does not output an error message.

Thanks & Regards Simon

SIGSEGV111 commented 9 years ago

I think I found the error. It was actually a configuration mistake on my side. My file task depended on itself. The dependency list is dynamically created by searching for all css files in the project. After the first run, this search would also include the library.css itself. My guess is that Jake ends up in an endless recursion until it exceeds its maximimum stack size.

It would be nice if Jake would check for such errors in the future. Nevertheless thanks for your help!

Regards Simon

veldsla commented 9 years ago

Hi all,

Interesting test case. The main difference between the 0.7 and v8 is that the task now has an additional status (STARTED). Before a prereq is started it is first checked that it hasn't already been started by another depending task. In this case this is true (the depending task is itself) and it avoids the recursive loop. It does wait for the complete event which can never be fired because of the circular dependency. I'm not yet sure why the downstream execution stops.

veldsla commented 9 years ago

I found a small (and stupid) issue regarding the task statuses. I also created a check in the async (parallel) loop that detects the single level cyclic dependency. I will create a PR for this. This only reports the issue when using parallelLimit.

I'm still not sure why the program exits when not all events have been captured I even tried adding a listener on the jake complete event in cli.js, but still node happily exits when there are several callbacks that have never been called.

SirAnthony commented 9 years ago

Spent whole day on debugging this (I have about 400 tasks which is hardly depend one on another). The problem is here: https://github.com/jakejs/jake/blob/master/lib/task/task.js#L192, It is self-dependency and must be partially fixed by #275.