代码之家  ›  专栏  ›  技术社区  ›  jlyh

云函数-函数执行完成,返回前状态为“OK”

  •  0
  • jlyh  · 技术社区  · 6 年前

    我有一个(gcp)cloud函数,它是用来聚合每小时数据并写入cloud bigtable的,但是它似乎返回消息:“函数执行花费了100毫秒,完成时状态为:OK”,在完成完整代码之前,后面的行有时会运行,有时不会。如果有任何人有任何经验并能就此提出建议,那就太好了,谢谢!

    当我运行脚本时,它在我的本地机器上工作,只在云函数中工作,我不确定是什么触发了代码的终止。我试图添加一个try/catch块,但它也没有抛出任何错误。代码的主要部分转载如下:

    const Bigtable = require('@google-cloud/bigtable');
    const bigtableOptions = { projectId: process.env.PROJECT_ID };
    const bigtable = new Bigtable(bigtableOptions);
    const cbt = bigtable.instance(process.env.BIGTABLE_INSTANCE);
    const async = require("async");
    const moment = require("moment");
    require("moment-round");
    const bigtableFetchRawDataForDmac = require("./fetchData").bigtableFetchRawDataForDmac;
    
    exports.patchJob = (event, context) => {
        const pubsubMsg = Buffer.from(event.data, 'base64').toString();
        const jsonMsg = tryParseJSON(pubsubMsg);    // msg in format { time: "2018-12-24T02:00:00.000Z", dmac: ["abc", "def", "ghi] }
        if(!jsonMsg) return;
        else {
            if(!jsonMsg.time) { 
                console.log("Time not provided");
                // res.status(400).json({ err: 'TimeNotProvided', msg: `Time parameter is not provided` });
                return;
            }
            let date_range = {};
            date_range.lower = moment(jsonMsg.time).toISOString();
            date_range.upper = moment(jsonMsg.time).add(1,'hours').subtract(1,"milliseconds").toISOString();
    
            let queryData = [];
            let data = {};
            for(let i=0; i<jsonMsg.dmac.length; i++){
                data[jsonMsg.dmac[i]]=[];
                queryData.push(bigtableFetchRawDataForDmac(cbt, jsonMsg.dmac[i], date_range.lower, date_range.upper, data[jsonMsg.dmac[i]]));
            }
            async.parallel(queryData, function(err, result){
                console.log("cookie trail...");
                return;
            }   
        }
    }
    

    对于bigtablefetchrawdatafordmac,它位于另一个文件夹中:

    function bigtableFetchRawDataForDmac(cbt, dmac, start, end, data) {
        return async function(cb){
            const table = cbt.table(process.env.BT_DATA_TABLE);
            try { var bigtable = await fetchFromBigtable(table, process.env.BT_DATA_TABLE, dmac, start, end, data, ['push', 'mode', 'val']); }
            catch (err) { console.log("bigtableFetchRawDataForDmac failed: ", err); cb(err); }
        }
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Doug Stevenson    6 年前

    pubsub Cloud Function 接收一个 event callback 参数。你应该调用回调方法 terminate the function 当所有工作都完成时,所有类型的 background Cloud Functions .

    你已经打过电话了 context . 而您根本没有使用它来终止函数。你也可以返回一个承诺,当所有的工作都完成时解决,但你也没有这样做。

    只有在完成所有异步工作之后,您才能找到一种方法来正确地终止您的函数,否则它将无法按您期望的方式工作。

        2
  •  0
  •   jlyh    6 年前

    在nodejs 8(beta)运行时,应该提供3个参数(数据、上下文、回调),而不是云函数控制台的内联编辑器中的默认模板中提供的2个参数。(文件参考: https://cloud.google.com/functions/docs/writing/background#functions_background_parameters-node8 )

    代码应该类似于:

    exports.patchJob = (event, context, callback) => {
        doSomething();
        callback(); // To terminate Cloud Functions
    }
    

    谢谢@doug的提示!