Error: Future resolved more than once? Even though correct result is returned?


#1

While running the below in a cron job:

 FutureTasks.upsert({
                    number: contentObj.records[i].number,
                    userid: contentObj.records[i].assigned_to_userid,
                    username: contentObj.records[i].assigned_to,
                    assignment_group: contentObj.records[i].assignment_group
                }, {
                    // Modifier
                    $set: {
                        start_date: moment(contentObj.records[i].start_date, "YYYY-MM-DD HH:mm:ss").subtract(1, 'hours').format("YYYY-MM-DD HH:mm:ss"),
                        end_date: moment(contentObj.records[i].end_date, "YYYY-MM-DD HH:mm:ss").add(1, 'hours').format("YYYY-MM-DD HH:mm:ss")
                    }
                }
                ,
                function (err, doc) {
                    if (err) {
                        console.log('error inside upsert : ', err.reason);
                        future.throw(err);
                    } else {
                        console.log('doc inside upsert : ', doc);
                        future.return(doc);
                    }
                }
            ); 
        } 
    } 

    try {
         return future.wait();
    }
  catch (err) {
        throw new Meteor.Error("insert-error", err);
    }
 },

I get correct response on console:

doc inside upsert :  { numberAffected: 1 }

and database is inserted (first run) or updated (in subsequent runs)

But at the same time also:

Exception in callback of async function: Error: Future resolved more than once

How to resolve such issue as I need to run the above code in a recurring cron loop?

Or I need to do db.close?

Thanks so much.


Exception in callback of async function: Error: Future resolved more than once
#2

I had a similar case in a parser and what I did is to add a flag to avoid the future getting resolved more than once. It removed the exception and still returned the correct result.


#3

Hi Diego, so is it a serious issue? Or something that can be ignored? Or any side effects that can pamper other promises along the chain?


#4

I could never figure out why the future was being resolved multiple times and I don’t know if it can be safely ignored. The only thing I can tell is in my case it has always returned correct results.


#5

It is because I had a asynchronous db.Collection.upsert asynchonrously called with a future being returned inside ‘for loop’, so to do a similar bulk find:

 FutureTasks.find({}, {fields: {start_date: true, _id: true}}).fetch().forEach(function (item) {
        console.log('read from Mongo Collection FutureTasks item is : ', item);
        console.log('read from Mongo Collection FutureTasks item._id is : ', item._id);
        console.log('read from Mongo Collection FutureTasks item.start_date is : ',     item.start_date);
        console.log('typeof item.start_date read from Mongo Collection FutureTasks is : ', typeof(item.start_date));
    },
    function (err, resp) {
        if (err) {
            future.return(err.reason);
        } else {
            future.return(resp);
        }
    });

    future.wait();
},

But I dont know how to do it for bulk upsert as I am reading from a JSON array as input


#6

Hi Diego

Where and how did you applied the flag as logic for this. Much appreciated. Please could you show an example.


#7

From the code

const parse = t => {

  const future = new Future()
  let future_resolved = false

  t.stream.on('line', string => {

    // Exit if should have already finished
    if (future_resolved) return

[…]

    // Process line by line
    if (match = regex.exec(string))
    if (env = extractor (match))
    for (let m in models) add_data (models[m], env, data[m])
  })

  t.stream.on('close', () => { if (!future_resolved) future['return']() })

  future.wait()
}