【问题标题】:How to make API calls idempotent in a Cloud Function trigger如何在 Cloud Function 触发器中使 API 调用具有幂等性
【发布时间】:2021-11-11 19:18:27
【问题描述】:

我有一个触发 API 的 onCreate 云函数,但我需要确保它不会触发两次。云函数触发器可以执行多次,我们鼓励使用 eventId 来实现幂等性。这是我目前拥有的:

    let ship_ref = admin.firestore().collection('shipments').doc(event_id)
    return admin.firestore().runTransaction(transaction => {
      return transaction.get(ship_ref)
      .then(ship_doc => {
        if (ship_doc.exists) {
          console.log('label already generated')
          return null 
        }
        // generate the label
        return axios({
          method: 'post',
          ...rest of the axios config
        })
        .then(label_response => {
          const label_data = label_response.data

          // add the label data to the shipment collection
          transaction.set(ship_ref, {
            ...sale_data,
            label_data,
            tracking_url_data,
            completed_sale_ref: snap.ref
          })
          return null
        })
        .catch(e => {
          // handle fail
        }) 
      })
    })
    .then(() => {
      // transaction complete
    })
    .catch(e => {
      // error
    })

这就是我所关心的。根据docs,如果文档的内容受到并发操作的影响,firestore 事务将再次运行。在这种情况下,如果它“再次运行”,它将再次运行 axios 调用,这对我不利。

如果云函数触发器(在本例中为 onCreate)运行多次,它是否有可能并发并导致竞争条件?如果是这样,那么 axios 请求可能会多次发出,这是我必须避免的。

提前感谢您的帮助。

【问题讨论】:

    标签: node.js firebase google-cloud-firestore google-cloud-functions


    【解决方案1】:

    如果云函数触发器(在本例中为 onCreate)运行多次,是否有可能并发并导致竞争条件?

    您可以假设重试不会与之前的调用重叠。可以这样想:如果你打电话给某人,但他们没有回应,同时再次给他们打电话并不会真正提高你抓住他们的机会。挂断后,您需要等待一段时间才能重试。这就是这里发生的事情。如果 Cloud Functions 与函数之间的消息由于某种原因第一次被丢弃,Cloud Functions 可能会尝试再次调用该函数。

    除此之外,您不应该在事务中执行有状态的工作。这本身就很糟糕。事务本身有自己的重试机制,以防该事务中的文档发生争用。事务处理程序应该是完全无状态的,并且只对正在处理的文档之外的静态数据进行操作。这在documentation 中有说明:

    使用事务时,注意...事务函数不应该直接修改应用程序状态。

    Also:

    请勿在事务函数中修改应用程序状态。这样做会引入并发问题,因为事务函数可以运行多次,并且不能保证在 UI 线程上运行。相反,将您需要的信息传递到您的交易功能之外。

    对 axios 的调用应该被视为应用程序状态,尤其是因为它是一个帖子。我会更进一步说事务处理程序也不应该阻塞。它们需要尽可能快地运行以减少争用。

    【讨论】:

    • 好的,知道了。感谢您的详细回复。我将删除事务,并在调用之前检查具有幂等文档 ID 的文档是否存在。从本质上讲,我担心的是你确认的,我不应该在交易中发布。
    猜你喜欢
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 2023-03-26
    • 2018-05-16
    相关资源
    最近更新 更多