function called twise in 'auto' mode #128

Closed
ghost opened this Issue May 8, 2012 · 6 comments

Comments

Projects
None yet
6 participants

ghost commented May 8, 2012

Let's say we have 3 functions: 2 and 3 depend on 1 (example).
In this case function 2 called twice.

Am I missing something?

var async = require('async');
var log = require("log4js").getLogger("test");

async.auto({
    task1:task1,
    task2:['task1', task2],
    task3:['task1', task3]
}, function (err) {
    log.info("finish");
});

function task1(callback) {
    log.info("task1: start");

    setTimeout(function () {
        log.info("task1: end");
        callback(null, this)
    }, 800);
}

function task2(callback) {
    log.info("task2: start");
    setTimeout(function () {
        log.info("task2: end");
        callback(null, this)
    }, 1000);
}

function task3(callback) {
    log.info("task3: start");
    log.info("task3: end");
    callback(null, this);
}

output

[2012-05-08 03:37:23.650] [INFO] test - task1: start
[2012-05-08 03:37:24.457] [INFO] test - task1: end
[2012-05-08 03:37:24.457] [INFO] test - task3: start
[2012-05-08 03:37:24.457] [INFO] test - task3: end
[2012-05-08 03:37:24.457] [INFO] test - task2: start
[2012-05-08 03:37:24.457] [INFO] test - task2: start
[2012-05-08 03:37:25.457] [INFO] test - task2: end
[2012-05-08 03:37:25.457] [INFO] test - finish
[2012-05-08 03:37:25.459] [INFO] test - task2: end
@akileh

This comment has been minimized.

Show comment Hide comment
@akileh

akileh May 9, 2012

Same problem, but seems to work fine in 0.1.15

akileh commented May 9, 2012

Same problem, but seems to work fine in 0.1.15

@jcayzac

This comment has been minimized.

Show comment Hide comment
@jcayzac

jcayzac May 10, 2012

Same problem here!

jcayzac commented May 10, 2012

Same problem here!

@allanca

This comment has been minimized.

Show comment Hide comment
@allanca

allanca May 30, 2012

Contributor

Ran into this too. Happens when one or more of the callbacks are not truly asynchronous. Like, in your example, task3.

Fix is to not allow tasks to be run more than once. See #134

Contributor

allanca commented May 30, 2012

Ran into this too. Happens when one or more of the callbacks are not truly asynchronous. Like, in your example, task3.

Fix is to not allow tasks to be run more than once. See #134

@dpatti

This comment has been minimized.

Show comment Hide comment
@dpatti

dpatti Jul 13, 2012

Contributor

I'm using async 0.1.22 with @allanca's patch and I am still seeing this problem. To reproduce:

async.auto({
  a: function(next) {
    console.log("a");
    setTimeout(function() {
      next();
    }, 0);
  },

  b: ["a", function(next) {
      console.log("b");
    }
  ],

  c: ["a", function(next) {
      console.log("c");
      next();
    }
  ]
});

What's happening is, b and c are setting up their listeners, and when a completes it iterates over the listeners to see who to call next. c gets called and finishes instantly, which means we are once again iterating over the tasks, at which point b gets called. So far we are in the same stack of a -> c -> b. Now b exits without completing, so we unwind back to c and then back to a, but here we still have another item in the listeners list since we slice(0) it and b was never removed. Now b is getting called again.

Contributor

dpatti commented Jul 13, 2012

I'm using async 0.1.22 with @allanca's patch and I am still seeing this problem. To reproduce:

async.auto({
  a: function(next) {
    console.log("a");
    setTimeout(function() {
      next();
    }, 0);
  },

  b: ["a", function(next) {
      console.log("b");
    }
  ],

  c: ["a", function(next) {
      console.log("c");
      next();
    }
  ]
});

What's happening is, b and c are setting up their listeners, and when a completes it iterates over the listeners to see who to call next. c gets called and finishes instantly, which means we are once again iterating over the tasks, at which point b gets called. So far we are in the same stack of a -> c -> b. Now b exits without completing, so we unwind back to c and then back to a, but here we still have another item in the listeners list since we slice(0) it and b was never removed. Now b is getting called again.

@danbell

This comment has been minimized.

Show comment Hide comment
@danbell

danbell Nov 22, 2012

Contributor

+1 for dpatti's fix. I've seen this issue too in 0.1.22. It occurs when t2 and t3 both depend on t1, and t1 doesn't complete immediately. Because the current test (to determine if a task is ready to execute) is looking at the "results" object, and t1 hasn't finished, both t2 and t3 can start a version of t1. dpatti's fix solves this issue.

Contributor

danbell commented Nov 22, 2012

+1 for dpatti's fix. I've seen this issue too in 0.1.22. It occurs when t2 and t3 both depend on t1, and t1 doesn't complete immediately. Because the current test (to determine if a task is ready to execute) is looking at the "results" object, and t1 hasn't finished, both t2 and t3 can start a version of t1. dpatti's fix solves this issue.

@caolan

This comment has been minimized.

Show comment Hide comment
@caolan

caolan Feb 4, 2013

Owner

Patched in 0.2.0.

Owner

caolan commented Feb 4, 2013

Patched in 0.2.0.

@caolan caolan closed this Feb 4, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment