我有一个使用koa的节点应用程序。它从外部应用程序接收特定资源上的webhook。
为了说明这一点,假设webhook通过POST请求向我发送了以下类型的对象:
{
'resource_id':'<SomeID>',
'resource_origin':'<SomeResourceOrigin>',
'value' : '<SomeValue>'
}
我想顺序执行来自同一来源的任何资源,以避免与我的执行相关的资源不同步。
我当时在考虑使用数据库作为锁,并使用cron对相同来源的每个资源依次执行我的进程。
但是我不确定这是最有效的方法。
所以我的问题在这里:
您是否知道一些方法/包/服务,允许我使用可以为每个起源实现的全局队列,以确保来自相同起源的资源将被同步执行,而无需按顺序处理所有Webhooks?如果不使用数据库,那就更好了。
最佳答案
如果我是您,那么我将从序列化所有Webhooks的处理开始。换句话说,无论您来自何处,我都建议您一次处理它们。在您的nodejs应用程序中使用一个简单的队列。
(一旦您确信自己可以正常工作,则可以根据来源对它们进行序列化。)
首先,构造函数(将其称为handleOneWebhook()
)以将传入的Webhooks作为Promise或异步函数进行处理。然后,您可以使用具有此大纲的代码来调用它们。
let busy= false
async function handleManyWebhooks (queue) {
if (busy) return
busy = true
while (queue.length > 0) {
const item = queue.shift()
await handleOneWebhook (item)
}
busy = false
}
传递给
queue
的handleManyWebhooks
是一个简单的数组,其中每个元素都是POST请求中的对象。您将其用作队列:push()
每个对象将其放入队列,并shift()
将其删除。然后,每当您收到一个webhook POST对象时,就使用带有此轮廓的代码。
const queue = []
...
function handlePostObject (postObject) {
queue.push(postObject)
handleManyWebooks (queue)
}
即使您为每个传入的对象调用一次handleManyWebhooks,
busy
标志也可以确保它一次仅处理一个。注意,这是一个非常简单的解决方案。一旦它正常工作,就会提出两个可能的改进。
使用比简单数组更有效的队列。
shift()
不太快。为每个单独的来源创建一个具有自己的
busy
标志的单独的队列对象。然后,您将能够并行化处理来自不同来源的Webhooks,同时仍然序列化来自每个来源的Webhooks流。关于node.js - 顺序执行 Node 应用程序中收到的Webhook,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56823472/