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

async._eachLimit halts one of N>1 concurrent tasks on error; keeps processing #649

Closed
aronatkins opened this issue Oct 29, 2014 · 0 comments
Labels

Comments

@aronatkins
Copy link

All async._eachLimit callers are subject to this issue, which includes:

  • async.eachLimit
  • async.parallelLimit
  • async.mapLimit

The effect is that when run with n=1, processing halts after the first error. When run with n>1 and a single error occurs, all other work is processed (though with less concurrency).

Here is an example of this behavior using mapLimit:

'use strict';

var async = require('async');

var parts = [ 1,2,3,4,5,6,7,8,9,10 ];
async.mapLimit(parts, 2, function(part, callback) {
  console.log('part',part);
  if (part === 4) {
    callback(new Error('four is fantastic'));
  } else {
    setTimeout(function() {
      console.log('finished',part);
      callback(null);
    }, 1000);
  }
}, function(err, result) {
     console.log('in finalizer');
     console.log(err,result);
});

When run with n=2, you will see that we call the finalizer and then continue processing the remaining items.

When run with n=1, work stops after an error occurs.

The _eachLimit inner replenish function should stop iteration if any concurrent task encounters an error. Something like:

            var erred = false;

            (function replenish () {
                if (completed >= arr.length) {
                    return callback();
                }

                while (running < limit && started < arr.length && !erred) {
                    started += 1;
                    running += 1;
                    iterator(arr[started - 1], function (err) {
                        if (err) {
                            callback(err);
                            callback = function () {};
                            //erred = true;
                        }
                        else {
                            completed += 1;
                            running -= 1;
                            if (completed >= arr.length) {
                                callback();
                            }
                            else {
                                replenish();
                            }
                        }
                    });
                }
            })();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants