Continue execution after sending response (Cloud Functions for Firebase)

前端 未结 3 681
醉话见心
醉话见心 2020-11-27 21:56

I\'m using Firebase Functions with https triggers, and I was wondering how long after sending the response to the client, the functions keeps executing. I want to send a res

相关标签:
3条回答
  • 2020-11-27 22:09

    TL;DR

    While https functions will terminate shortly after res.send(), it is not guaranteed that 0 lines of code after res.send() will be executed.

    I think a fuller answer has 2 components:

    1. as Doug pointed out, do not put any additional code you expect to be executed after res.send()
    2. cloud functions will terminate shortly after res.send(), but don't expect that exactly 0 lines of code will be executed

    I ran into a situation where for a db maintenance script, if no records met my criteria, I said goodbye with res.send() and had additional logic after it. I was expecting that piece not to be run, since I've already terminated the request.

    Example producing unexpected results:

    exports.someFunction = functions.https.onRequest((req, res) => {
      if (exitCriteria === true) {
        // we can exit the function, nothing to do
        console.log('Exit criteria met')
        res.status(200).send()
      }
    
      // code to handle if someCriteria was falsy
      console.log('Exit criteria not met, continue executing code')
    })
    

    In the above example, I was expecting res.send() to terminate the function immediately - this is not so, the second console.log may also be hit - along with any other code you may have. This is not guaranteed, however, so execution may abruptly stop at some point.

    Example producing correct results:

    exports.someFunction = functions.https.onRequest((req, res) => {
      if (exitCriteria === true) {
        // we can exit the function, nothing to do
        console.log('Exit criteria met')
        res.status(200).send()
      }
      else {
        // code to handle if someCriteria was falsy
        console.log('Exit criteria not met, continue executing code')
      }
    })
    

    In this version, you will see exactly 1 line of console.logs - as I was originally intending.

    0 讨论(0)
  • 2020-11-27 22:19

    You should expect that the HTTP function terminates the moment after you send the response. Any other behavior is some combination of luck or a race condition. Don't write code that depends on luck.

    If you need to send a response to the client before the work is fully complete, you will need to kick off a second function to continue where the HTTP function left off. It's common to use a pub/sub function to do with. Have the HTTP function send a pub/sub message to another function, then terminate the HTTP function (by sending a response) only after the message is sent.

    0 讨论(0)
  • 2020-11-27 22:21

    If the expected response is not pegged to the outcome of the execution, then you can use

    module.exports.doSomeJob = functions.https.onRequest((req, res) => {
    res.write('SUCCESS')
    return doSomeAsyncJob()
    .then(() => {
        emailSender.sendEmail();
    })
    .then(() => {
        res.end();
    })
    .catch(...);
    });
    

    This sends back a response a soon as a request is received, but keeps the function running until res.end() is called Your client can end the connection as soon as a response is received back, but the cloud function will keep running in the background Not sure if this helps, but it might be a workaround where the client needs a response within a very limited time, considering that executing pub/sub requires some extra processing on its own and takes time to execute

    0 讨论(0)
提交回复
热议问题