Firebase触发器函数执行顺序如何处理 [英] How to deal with firebase trigger function execution order

查看:62
本文介绍了Firebase触发器函数执行顺序如何处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个firebase http函数,可将数据追加到firebase数据库列表中.第二个功能配置为在列表更改时处理列表,然后更新一些摘要数据.就我而言,这些更新是连发的.我正在使用node.js firebase函数.

I have a firebase http function which appends data to a firebase database list. A second function is configured to process the list when it changes and then update some summary data. In my case, these updates come in bursts. I'm using node.js firebase functions.

在查看Firebase日志时,我从一个空列表开始看到以下顺序:

Looking at the firebase logs, I see this sequence when starting with an empty list:

  1. 从http添加到列表-列表包含1个元素
  2. 从http添加到列表-列表包含2个元素
  3. 从http添加到列表-列表包含3个元素
  4. 从http添加到列表-列表包含4个元素
  5. 汇总包含1个元素的列表
  6. 汇总包含3个元素的列表
  7. 汇总包含4个元素的列表
  8. 汇总包含2个元素的列表

我的问题是摘要仅包含2个元素,而不是4个.

My problem is the summary only includes 2 elements instead of 4.

似乎汇总触发函数是并行而不是顺序调用的,因此,当多个触发紧密相邻时,最后要完成的触发可能是最早触发的触发之一,而不是最后触发.

It would appear the summarize trigger functions are invoked in parallel instead of sequential so when several trigger in close proximity, the last one to finish may be be one of the first ones triggered instead of the last.

可以使用哪些方法来确保摘要计算具有所有数据",并且先前的摘要计算运行速度较慢,不会覆盖后面的摘要计算?是否可以序列化firebase函数触发器以按其启动顺序执行?

What approaches can be used to insure the summary computation has 'all the data' and a prior summary computation running slower doesn't overwrite a later one? Can firebase function triggers be serialized to execute in the order they are initiated?

理想情况下,我想避免在发生突发时计算N次摘要,因此某些解决方案可以在将来的短时间内安排"摘要,然后在发生新事件时取消并重新安排摘要很好.

Ideally I'd like to avoid computing the summary N times when a burst comes in so some solution where the summary could be 'scheduled' for some short time in the future and then canceled and rescheduled if a new event comes in would be nice.

推荐答案

我的解决方法是将admin.database.ServerValue.TIMESTAMP与列表添加在一起,并在结果计算器中验证它是否产生了最新时间戳的结果.如果没有,它将重试.在大多数情况下,由于我的输入源通常是零星的单个列表添加而不是集总添加,因此不需要重新计算摘要.我将其实现为返回Promise的函数,该Promise会在必要时自行进行重新计算.这是顺序:

My workaround is to store a admin.database.ServerValue.TIMESTAMP with the list add and verify in the results calculator that it produced results for the latest timestamp. If not, it tries again. In most cases it will not need to recompute the summary as my input source is normally sporadic single list adds rather than lumped additions. I implemented this as a function returning a Promise that calls itself if necessary to recompute. This is the sequence:

  1. 读取当前列表和时间戳
  2. 计算摘要结果并将其存储
  3. 再次阅读时间戳
  4. 如果时间戳记不同,则转到1,否则完成

代码如下:

/// return a Promise that new summary and detail results will be posted
function updateResults(regattaId, lapdataTS, depth) {
  if (depth > 10) {
    return Promise.reject("Too many recomputes");
  }
  return admin.database().ref('/eventdata/'+regattaId).once('value')
  .then(function (snapshot) {
    const rawdata = snapshot.val(); 

    if (rawdata.lapdataTS === lapdataTS) {
        // console.log("already computed");
        return Promise.resolve();
    }
    lapdataTS = rawdata.lapdataTS ? rawdata.lapdataTS : null;
    const results = regattaCalc.computeResults(rawdata);

    var updates = {};
    updates['results/' + regattaId] = results;
    updates['summary/' + regattaId] = results.regattaInfo;
    return admin.database().ref().update(updates);
  }).then(function () {
    // read last TS and see if it matches our summary
    return admin.database().ref('/eventdata/'+regattaId+'/lapdataTS').once('value');
  }).then(function (snapshot) {
   if (snapshot.val() === lapdataTS) {  
       return Promise.resolve();
   } else {
       //console.log("Need to calc again");
       return updateResults(regattaId, lapdataTS, depth++);
   }
  }).catch((reason) => {
    console.log("Error generating summary: " + reason);
    return Promise.reject(reason);
  });
}

exports.compupteResults = functions.database.ref('/eventdata/{regattaId}').onWrite(event => {
return updateResults(regattaId,null,0);
 });

这篇关于Firebase触发器函数执行顺序如何处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆