Binding Mongoose models save method inside async.auto #178

Closed
lbeschastny opened this Issue Sep 14, 2012 · 6 comments

4 participants

@lbeschastny

Right now I'm working with both mongoose 3.1.1 and async 0.1.22.
But when I tried to save Mongoose models instance inside async.auto it just stopped working.

See the following example and try it by yourself:

mongoose = require 'mongoose'
async = require 'async'
Schema = mongoose.Schema
ObjectId = Schema.ObjectId

mongoose.connect "mongodb://localhost:27017/async-test"

SmthSchema = new Schema
  data : type: String

mongoose.model 'Smth', SmthSchema
Smth = mongoose.model 'Smth'

test1 = (next) ->
  console.log '  test 1'
  smth = new Smth data: 'some data'

  async.auto
    first: (callback) ->
      smth.save callback
    second: ['first', (callback) ->
      console.log '  it works!'
      callback()]
    next

test2 = (next) ->
  console.log '  test 2'
  smth = new Smth data: 'some data'

  async.series [
    smth.save.bind smth
    (callback) ->
      console.log '  it works!'
      callback()
  ], next

test3 = (next) ->
  console.log '  test 3'
  context =
    save: (callback) -> callback null

  async.auto
    first: context.save.bind context
    second: ['first', (callback) ->
      console.log '  it works!'
      callback()]
    next

test4 = (next) ->
  console.log '  test 4'
  smth = new Smth data: 'some data'

  async.auto
    first: smth.save.bind smth
    second: ['first', (callback) ->
      console.log '  it works!'
      callback()]
    next

console.log 'running all tests'
async.series [test1, test2, test3, test4], (err) ->
  console.log err || 'all works!'

Resulting output:

running all tests
  test 1
  it works!
  test 2
  it works!
  test 3
  it works!
  test 4

smth.save.bind smth binds save function to the object it shall save. It works great in async.series and async.parallel, but not in async.auto.

async.auto saves the object to database, but it looses callback and processing stops.

The strangest thing is than i never had any problems neither with binding anything else inside of async.auto nor with binding Mongoose save method in any other context.

Is it async's problem or shall I write the same issue to mongoose? Thanks.

@lbeschastny

I just found another example of async.auto breakage. In the following example async.auto calls one of its tasks multiple times:

console.log 'before auto'
async.auto
  a: (callback) ->
    console.log 'a'
    smth = new Smth data: 'some data'
    smth.save callback
  b1: ['a', (callback) ->
    console.log 'b1'
    smth = new Smth data: 'some data'
    smth.save callback]
  b2: ['a', (callback) ->
    console.log 'b2'
    callback()]
  (err,res) ->
    console.log 'after auto'

Resulting output:

before auto
a
b2
b1
b1
after auto

The strangest thing is that the following code works just great:

console.log 'before auto'
async.auto
  a: (callback) ->
    console.log 'a'
    smth = new Smth data: 'some data'
    smth.save callback
  b2: ['a', (callback) ->
    console.log 'b2'
    callback()]
  b1: ['a', (callback) ->
    console.log 'b1'
    smth = new Smth data: 'some data'
    smth.save callback]
  (err,res) ->
    console.log 'after auto'

It's output:

before auto
a
b1
b2
after auto

Obviously, async.auto breaks somewhere when it works with Mongoose method save. But I can't understand where and why.

@mostlygeek

It's not mongoose. I ran into this issue too.
There is a bug in async.auto. It's caused by calling callback() in the same tick of the event loop. See:

see:
#128
#134
#148

@mikermcneil

I'm also having the same problem (I'm using Sequelize)

@lbeschastny

@mikermcneil, it solves the problem with multiple calls, but binding Mongoose models save method still breaks.

@caolan
Owner

Using synchronous functions with async.auto should work in 0.2.0 ...I'd still recommend you don't use synchronous functions with async though. Functions should be consistently asynchronous or consistently synchronous in Node.

@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