首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Firestore事务处理非常慢(3-4分钟)

Firestore事务处理非常慢(3-4分钟)
EN

Stack Overflow用户
提问于 2020-12-06 19:53:04
回答 2查看 811关注 0票数 1

编辑:删除无关的代码,以提高可读性,编辑2:将示例简化为仅uploadGameRound函数,并添加日志输出的次数。

我正在开发一款移动多人字游戏,之前我使用过Firebase实时数据库,除了冷启动之外,它的性能也相当出色。保存更新的游戏和设置统计数据最多需要几秒钟。最近,我决定对我的游戏数据和玩家统计数据/顶级列表使用Firestore,主要是因为更高级的查询和自动缩放,而不需要手动分片。现在我已经做了一些关于Firestore的工作,但是保存一个更新的游戏和更新一些统计数据所花费的时间实在是太荒谬了。我在游戏更新前3-4分钟内平均计时,添加了统计数据,所有数据都可以在数据库中为其他客户提供,并可在web界面中查看。我猜测并希望这是因为我在实现中搞砸了一些事情,但是这些事务都经过了,并且没有任何警告或其他任何事情可以真正进行。查看云函数日志,函数调用到完成日志语句的总时间似乎超过了一分钟,但在相同的3-4分钟等待数据之后,日志才会出现。

这是它的代码。如果有人有时间看一看,也许发现出了什么问题,我会非常感激的!

这个函数是从Unity:调用的

代码语言:javascript
复制
exports.uploadGameRound = functions.https.onCall((roundUploadData, response) => {

    console.log("UPLOADING GAME ROUND. TIME: ");
    var d = new Date();
    var n = d.toLocaleTimeString();
    console.log(n);

    //  CODE REMOVED FOR READABILITY. JUST PREPARING SOME VARIABLES TO USE BELOW. NOTHING HEAVY, NO DATABASE TRANSACTIONS.  //
    
    
    // Get a new write batch
    const batch = firestoreDatabase.batch();

    // Save game info to activeGamesInfo
    var gameInfoRef = firestoreDatabase.collection('activeGamesInfo').doc(gameId);

        batch.set(gameInfoRef, gameInfo);

        // Save game data to activeGamesData
        const gameDataRef = firestoreDatabase.collection('activeGamesData').doc(gameId);
        batch.set(gameDataRef, { gameDataCompressed: updatedGameDataGzippedString });


    if (foundWord !== undefined && foundWord !== null) {

        const wordId = foundWord.timeStamp + "_" + foundWord.word;

        // Save word to allFoundWords
        const wordRef = firestoreDatabase.collection('allFoundWords').doc(wordId);
        batch.set(wordRef, foundWord);

        exports.incrementNumberOfTimesWordFound(gameInfo.language, foundWord.word);

    }

    console.log("COMMITTING BATCH. TIME: ");
    var d = new Date();
    var n = d.toLocaleTimeString();
    console.log(n);


    // Commit the batch
    batch.commit().then(result => {
        return gameInfoRef.update({ roundUploaded: true }).then(function (result2) {


            console.log("DONE COMMITTING BATCH. TIME: ");
            var d = new Date();
            var n = d.toLocaleTimeString();
            console.log(n);
            
            return;
        });

    });

});

再一次,任何帮助理解这种奇怪的行为是非常感谢的!

EN

回答 2

Stack Overflow用户

发布于 2020-12-08 11:19:41

好吧,现在我发现了这个问题,我想我应该和大家分享一下:

只需在批处理提交之前添加一个返回语句,就可以修复函数,并将时间从4分钟缩短到不到1秒:

代码语言:javascript
复制
RETURN batch.commit().then(result => {
        return gameInfoRef.update({ roundUploaded: true }).then(function (result2) {


            console.log("DONE COMMITTING BATCH. TIME: ");
            var d = new Date();
            var n = d.toLocaleTimeString();
            console.log(n);
            
            return;
        });

    });
票数 1
EN

Stack Overflow用户

发布于 2020-12-07 16:59:16

您的函数不会返回与发送给客户端应用程序的数据一起解析的承诺。如果没有返回的承诺,它将立即返回,不能保证任何挂起的异步工作将正确终止。

在单个承诺上调用then并不足以处理承诺。您可能需要在commit()和其他函数(如incrementNumberOfTimesWordFound )之间进行大量异步工作。您将需要正确地处理所有的承诺,并确保您的整体功能只返回一个承诺,该承诺在所有工作完成后得到解决。

我强烈建议花点时间来学习在JavaScript中承诺是如何工作的--这对于编写有效的函数至关重要。如果没有充分的理解,事情就会以奇怪的方式出现问题,或者根本不会出错。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65172430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档