繁体   English   中英

我如何知道 Stream(Node.js、MongoDB)何时准备好进行更改?

[英]How do I know when a Stream (Node.js, MongoDB) is ready for changes?

我想确保Stream已准备好进行更改,然后才能将数据发送到客户端。 我的代码:

// Get the Stream (MongoDB collection)
let stream = collection.watch()
// Generate identifier to send it to the client
const uuid = uuid()
// Listen for changes
stream
  .on('change', () => {
    // Send something to WebSocket client
    webSocket.emit('identifier', uuid)
  })

// Mutate data base collection to kick off the "change" event
await collection.updateOne()

webSocket.emit的行是我的问题。 我如何知道Stream是否已经准备好接收事件? 碰巧change事件永远不会发生,因此webSocket.emit永远不会被调用。

TL;博士

基本上,我需要向客户端发送一些东西,但需要确保Stream已准备好在此之前接收事件。

这看起来像是在 changeStream 聚合管道到达服务器之前执行更新查询的竞争条件。 基本上,您需要等待 stream cursor 设置好后才能触发更改。

我找不到任何“光标就绪”事件,因此作为一种解决方法,您可以检查其 ID。 它由服务器分配,因此当它在客户端可用时,它有点保证将捕获所有连续的数据更改。

像这样的东西应该可以完成这项工作:

async function streamReady(stream) {
    return new Promise(ok => {
        const i = setInterval(() => {
            if (stream.cursor.cursorState.cursorId) {
                clearInterval(i);
                return ok()
            }
        }, 1)
    });
}

然后在您的代码中:

// Get the Stream (MongoDB collection)
let stream = collection.watch()
// Generate identifier to send it to the client
const uuid = uuid()
// Listen for changes
stream
  .on('change', () => {
    // Send something to WebSocket client
    webSocket.emit('identifier', uuid)
  })

await streamReady(stream);    

// Mutate data base collection to kick off the "change" event
await collection.updateOne()

免责声明:

上面的 streamReady function 依赖于cursorState 它是一个内部字段,即使在驱动程序的补丁版本更新中也可以更改,恕不另行通知。

我已经设法在不使用 API 的未记录部分的情况下完成这项工作。

    await new Promise<void>((resolve) => {
      changeStream.once('resumeTokenChanged', () => {
        resolve();
      });
    });

我正在使用resumeTokenChanged事件。 这对我有用。

暂无
暂无

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

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