0

In Tips & Tricks the docs say

Note: If a Node.js background function returns a Promise, Cloud Functions ensures that the Promise is settled before terminating.

My question is, does this ensurance extend to anonymous callbacks that are returned from a non-promised method?

export const mutateData = functions.https.onCall(async (data, context)=>{
    const data = await getAndMutateData();

    await Promise.all([
        furtherMutate(data.data1),
        furtherMutate(data.data2),
        furtherMutate(data.data3)
    ]);

    const addendum = {
        addedData1: foo,
        addedData2: bar,
        addedData3: foobar
    };

    // Not awaited, we want to do this in the background while the client gets the status back
    data.writeCallback(addendum);

    return "success";
}

async function getAndMutateData(){
    let [data1, data2, data3] = await Promise.all([firestoreGetter1(), firestoreGetter2(), firestoreGetter3()]);

    mutate(data1);
    mutate(data2);
    mutate(data3);

    return {
        data1: data1,
        data2: data2,
        data3: data3,
        writeCallback: async function(addendum): Promise<any>{
            return Promise.all([
              firestoreSetter1(data1, addendum.addedData1),    // Merges data streams
              firestoreSetter2(data2, addendum.addedData2),
              firestoreSetter3(data3, addendum.addedData3)
            ]);
       }
    }
} 

Will the cloud instance close before the writeCallback has had a chance to finish? I want to give the client the success/fail status without waiting for the firestore writes to complete. There are other failsafes in place for that case.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
cjcurrie
  • 624
  • 1
  • 4
  • 15

1 Answers1

3

Firstly, the tip you cite applies only to background functions. The callable function you show here is not a background function. HTTP and callables are synchronous with the client that invokes them.

Will the cloud instance close before the writeCallback has had a chance to finish?

Yes, it will. You will need to await it if you want the function to complete before the function shuts down forcibly. You can't leave async work "dangling" when the function terminates, otherwise it might have strange behavior, or simply not work at all.

For callable functions, you are obliged to return a promise that becomes fulfilled with the data to send to the client, only after all the async work is complete. If you are trying to allow some work to continue after the client receives its response, you should refer to these:

The most common way of continue work after sending a response is to write a pubsub function to perform the extra work, then send a message to it from the main function.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441