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

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.

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.

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?

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.

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

Hi Diego

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

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()
}