xaphod
xaphod

Reputation: 6804

Firebase functions: how best to await unblocking promises after response is sent?

I'm using Express in Firebase Functions that are on Node 10. My question is: if I have heavy Promises that I need to complete before the function terminates, but I want to do this after I sent the response (res.status(200).send...), how is the best way I could do this?

I have come up with two approaches so far but neither seem great (and I haven't tried the 'finish' approach yet to see if it works):

  1. For every router, add a finally... clause that awaits accumulated promises. This has the major downside that it'd be easy to forget to do this when adding a new router, or might have bugs if the router already needs its own finally clause

  2. Use the Node stream 'finish' event, https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_event_finish ... but I don't know if Firebase Functions allow this to be caught, or if it'll still be caught if my function runs to its end and the event is fired afterwards.

I'm doing this to try to make my functions' responses faster. Thanks for any help.

Upvotes: 2

Views: 145

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317362

if I have heavy Promises that I need to complete before the function terminates, but I want to do this after I sent the response (res.status(200).send...), how is the best way I could do this?

With Cloud Functions, it's not possible to send a response before promises are resolved, and have the work from those promises complete normally. When you send the response, Cloud Functions assumes that's the very last thing the function will do. When the response is sent using res.send(), Cloud Functions will terminate the function and shut down the code. Any incomplete asynchronous work might never finish.

If you want to continue work after a response is sent, you will have to first offload that work to some other component or service that is not in the critical path of the function. One option is to send a message to a pubsub function, and let that function finish in the "background" while the first function sends the response and terminates. You could also send messages to other services, such as App Engine or Compute Engine, or even kick off work in other clouds to finish asynchronously.

See also:

Upvotes: 3

Related Questions