![](/img/trans.png)
[英]What is the correct way to publish to GCP PubSub from a Cloud Function?
[英]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.