Firestore偶尔会触发超时

时间:2018-12-11 19:34:46

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

我有一个Cloud Firestore trigger,负责调整我应用程序中用户钱包的余额。

exports.onCreateTransaction = functions.firestore
    .document('accounts/{accountId}/transactions/{transactionId}')
    .onCreate(async (snap, context) => {
        const { accountId, transactionId  } = context.params;

        const transaction = snap.data();

        // See the implementation of alreadyTriggered in the next code block
        const alreadyTriggered = await firestoreHelpers.triggers.alreadyTriggered(context);

        if (alreadyTriggered) {
            return null;
        }

        if (transaction.status === 'confirmed') {
            const accountRef = firestore
                .collection('accounts')
                .doc(accountId);

            const account = (await accountRef.get()).data();
            const balance = transaction.type === 'deposit' ? 
                    account.balance + transaction.amount : 
                    account.balance - transaction.amount;

            await accountRef.update({ balance });
        }

        return snap.ref.update({ id: transactionId });
    });

实际上,触发器可能be called more than once是触发器,所以我添加了此alreadyTriggered帮助函数:

const alreadyTriggered = (event) => {
    return firestore.runTransaction(async transaction => {
        const { eventId } = event;
        const metaEventRef = firestore.doc(`metaEvents/${eventId}`);
        const metaEvent = await transaction.get(metaEventRef);

        if (metaEvent.exists) {
            console.error(`Already triggered function for event: ${eventId}`);
            return true;
        } else {
            await transaction.set(metaEventRef, event);
            return false;
        }
    })
};

大多数时候,一切都会按预期进行。但是,今天我收到一个超时错误,该错误导致数据库中的数据不一致。

  

函数执行耗时60005毫秒,状态为:“超时”

此超时的原因是什么?以及如何确保不再发生这种情况,以便我的交易金额成功反映在帐户余额中?

1 个答案:

答案 0 :(得分:0)

如上所述,关于执行不止一次的声明是beta限制。 Cloud Functions现在处于beta版本之外。默认情况下,当前保证为at-least-once执行。如果您在Cloud控制台中enable retries,则只会收到多个可能的事件。如果要确保事件得到可靠处理,应该执行此操作。

可能无法确定超时的原因。可能有很多原因。也许是网络出现了打system,或者系统中某处发生了短暂的停机。重试应该通过潜在地多次传递事件来帮助您从这些临时情况中恢复,从而使您的功能得以成功。