node.js - Firestore 偶尔会触发超时

标签 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;
        }
    })
};

大多数时候一切都会按预期进行。然而,今天我遇到了超时错误,导致数据库中的数据不一致。

Function execution took 60005 ms, finished with status: 'timeout'

这次超时的原因是什么?我如何确保这种情况不再发生,以便我的交易金额成功反射(reflect)在账户余额中?

最佳答案

如上所述,有关多次执行的声明是测试版限制。 Cloud Functions 现已结束测试版。目前的保证是at-least-once默认执行。如果您enable retries,您只会得到多个可能的事件在云控制台中。如果您想确保事件得到可靠处理,您应该这样做。

超时的原因可能永远无法确定。原因可能有很多。也许网络出现了问题,或者系统某个地方出现了短暂的停机。重试应该可以通过多次传递事件来帮助您从这些临时情况中恢复,以便您的函数能够成功。

关于node.js - Firestore 偶尔会触发超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53731155/

相关文章:

javascript - 将类型传递给依赖注入(inject)容器

javascript - 路由中具有变量/id的Socket.io命名空间

firebase - 部署到 firebase 云功能时出错 - ?缺少配置详细信息

angular - 如何更改 Cloud Firestore 中数组内的对象?

firebase - Firestore 安全规则。允许阅读完整集合(文档和子集合)

mysql - 为什么我从 docker Node 应用程序连接到 localhost MySQL 时出现 ECONNREFUSED?

javascript - 等待直到内部函数被触发

android - 应用未打开时显示抬头通知

typescript - 配置 Firestore 安全规则以允许用户仅高效地访问他们自己的数据

javascript - 在 Node.JS 中使用 ECMAScript 6