繁体   English   中英

GCP Nodejs8 Cloud Function - 同步 PubSub 发布

[英]GCP Nodejs8 Cloud Function - Synchronous PubSub publish

我正在努力使用 javascript/Nodejs8 Google Cloud Function 将有效负载发布到 Google PubSub。

所以我有一个由 HTTP 请求触发的云 Function,然后请求正文被发布到一个 pubsub 主题(配置为拉模式)。

这是我的代码:

const {PubSub} = require('@google-cloud/pubsub');
const pubsub = new PubSub();
const topic = pubsub.topic('my-fancy-topic');

function formatPubSubMessage(reqObj){
    // the body is pure text
    return Buffer.from(reqObj.body);
};

exports.entryPoint = function validate(req, res) {

topic.publish(formatPubSubMessage(req)).then((messageId) => {
            console.log("sent pubsub message with id :: " + messageId)
        });

res.status(200).json({"res":"OK"});
};

我的问题是云 function 在发布 pubsub 消息之前完成执行(在日志中,日志“函数执行需要 X 毫秒,以状态代码完成:200”在我的 pubsub 日志之前大约 30 或 40 秒出现。我也有几次日志“忽略已完成功能的异常”,但我没有得到我的 pubsub 日志)

我不是 javascript 或 nodejs 专家,我也不掌握 javascript 的承诺,但我想知道是否可以使发布同步。 我也在想我可能在这里做错了什么!

预先感谢您的帮助。

现在,此代码在发布完成之前发送响应。 发送响应后,function 将终止,正在进行的异步工作可能无法完成。

相反,您应该做的是仅在发布完成后发送响应,这意味着将该行代码放在then回调中。

exports.entryPoint = function validate(req, res) {

    topic.publish(formatPubSubMessage(req)).then((messageId) => {
        console.log("sent pubsub message with id :: " + messageId)
        res.status(200).json({"res":"OK"});
    });

};

我建议花一些时间了解 Promise 是如何工作的,因为这对于构建正确工作的函数至关重要。

在您的逻辑中,当 HTTP 消息到达时,正在调用您的回调/事件处理程序 function。 然后执行 publish() function。 执行发布是一个异步活动。 这意味着发布需要一些时间才能完成,并且由于 JavaScript(本质上)不想阻止,它会立即返回 promise,然后您可以使用它在异步工作完成时收到通知。 在执行 publish() 之后,您的逻辑立即执行 res.status(....) ,它发送对 HTTP 请求的响应,这确实是来自 HTTP 客户端的流请求的结束。 异步发布仍在进行中,当它本身完成时,会发生发布回调并记录响应。

不幸的是,这不是谷歌在这里记录的好习惯......

https://cloud.google.com/functions/docs/bestpractices/tips#do_not_start_background_activities

在最后一个故事中,您调用validate的 function 仍将在发布完成之前结束。 如果您想在 publish() 执行时阻塞(有效地使其同步),您可以使用 JavaScript await关键字。 松散地,像:

try {
   let messageId = await topic.publish(....);
   console.log(...);
catch(e) {
 ...
}

您还需要将函数标记为async 例如:

exports.entryPoint = async function validate(req, res) {
   ...

请参阅: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

You can also simply return a Promise from the function and the callback function will not be considered resolved until the Promise as a whole is resolved.

底线是深入研究 Promise。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM