Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File changes that happen while a watch task is running get ignored #259

Closed
russelldavis opened this issue Dec 11, 2013 · 2 comments
Closed

Comments

@russelldavis
Copy link

This is an expanded version of issue #33. That issue was closed, but the problem still exists since the commit that fixed it got reverted. I have some more details that should be helpful.

Start with this Gruntfile.js (slightly modified from the one is issue 33):

module.exports = function(grunt) {
  grunt.initConfig({
    watch: {
      gruntfile: {
        files: 'Gruntfile.js',
        tasks: ['longtask']
      },
      shorttask: {
        files: 'shorttask',
        tasks: ['shorttask']
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('shorttask', function(){
    console.log('shorttask');
  });

  grunt.registerTask('longtask', function(){
    var originalGrunt = grunt.file.read('Gruntfile.js');
    var done = this.async();
    setTimeout(function(){
      grunt.file.write('Gruntfile.bak', originalGrunt);
      done();
    }, 10000);
  });

  grunt.registerTask('default', 'watch');
};

Create a file called shorttask in the same directory. Now, run grunt watch, then touch Gruntfile.js. Then, while 'longtask' is still running, run touch Gruntfile.js again. You'll notice that 'longtask' does not run again after it finishes. This was the original problem reported in issue 33.

However, you'll notice if you change the last step in the paragraph above to touch shorttask, then 'shorttask' will run after 'longtask' finishes. So, the problem above only applies to modifying files from the same watch group as the task that is running. I believe this is due to this line in watch.js.

But wait, there's more. If you repeat that, but first add options: {nospawn: true} to the watch config, then 'shorttask' will not run after 'longtask' finishes. When nospawn is set, the problem applies regardless of which watch group is modified.

To summarize:

  1. Regardless of nospawn, modifications to a file from a watch group whose tasks are currently running get ignored.
  2. When nospawn is true, modifications to a file from any watch group get ignored when any watch group's tasks are running.
@shama
Copy link
Member

shama commented Dec 11, 2013

The behavior with spawn: true or the default is desired. Otherwise rapid file changes, especially with chained watched/triggered groups will cause infinite loops. #33 and d01491b isn't an adequate solution for this feature.

With spawn: false, unfortunately that is the limitations of how Grunt runs tasks, in a series. The watch task must stop before it can run other tasks. I'm looking into a solution for that within the current infrastructure but ideally we should break out and enhanced the Grunt task runner into it's own library to support this behavior. I've opened #258 for this but I'm more focused on breaking out the task runner as that will eventually solve more outstanding issues.

Happy to accept a PR with tests for this behavior if anyone has a better solution for this within the current infrastructure. Thanks!

@shama shama closed this as completed Dec 11, 2013
@russelldavis
Copy link
Author

For spawn: true: I understand that the specific implementation for #33 caused infinite loops, but there certainly exists some way to fix it without doing that. I think ignoring changes should never be the desired behavior.

For spawn: false, #258 may be related, but I'm pretty sure that's not the direct cause here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants