RethinkDb 中的更改源是否总是阻塞?
是的,它必须是一个阻塞队列,以便让您的代码接受来自该 changefeed 的更改流中的每个元素(文档说:与其他游标不同,更改的输出是无限的:游标将阻塞直到有更多元素可用。)。
在主线程中运行它会永远阻塞线程。
并非如此:您仍然可以控制您的线程,从 changefeed 获得一个新值,并且您可以做其他事情,而不仅仅是打印一个 change 元素或只是打破 for 语句。
但是是的,在从 RethinkDB 连接读取下一个 changefeed 值之前,它会被阻止。
有没有我错过的回调版本?
不,但如果您确实需要,您可以轻松地围绕 r.changes() 方法实现面向回调的代码。
建议在线程中运行更改提要循环吗?这样做有什么问题吗?
这取决于您的特定应用程序是如何设计的。
您可能有一个单线程应用程序,它侦听无限的 changefeed 并执行其他操作,而不仅仅是打印新的 change 值。
如果您的应用程序应该做的不仅仅是监听 changefeed,那么是的,您必须创建一个新线程并遍历该线程上的 changefeed 流。
在 node.js 中是一样的吗? (记得在 node.js 示例中看到一些回调,但也许这只是异步 .run 调用)
是的,这只是因为 node.js 鼓励应用程序完全异步。
一旦您使用cursor.each(console.log); 读取changefeed 游标,它将像Python 版本一样无限运行(但是,我真的不记得如何破坏each 方法)。
Java 与 JavaScript 不同,但与 Python 相似,它还允许使用更改和阻塞遍历光标中的每个元素,直到接受新的更改。
找不到任何实际使用的例子,文档只是告诉你打开一个单独的终端窗口/python进程并在那里运行它。
嗯,这是演示其工作原理的最简单示例:您在某个 changefeed 上监听更改(让它只是一个在终端中运行的简单 CLI 应用程序),然后在您使用更改的同时做任何您想做的事情从其他地方更改数据库(它可能是内置的 Web 界面、recli、基于 RethinkDB 的应用程序等)。
我可以分享我之前在 Java(+ Spring 框架)中第一次使用 RethinkDB 的经验中的一个简单的真实示例:假设您有一个文档转换 REST 服务,它只接受某些文档并将它们转换为图片,但您还想在浏览器中实时监控转换状态。
它是如何实现的:
- REST 服务可以接受多个连接来并行处理多个转换请求(当然必须是多线程的)。这些请求转换上传的文档并将其转换状态保存到 RethinkDB 数据库中的特定表中。
- 此外,此 REST 服务在单独的“永久”线程中使用
r.changes() 方法监听 RethinkDB 数据库中表的更改,以无限地从表中读取状态,并通过 Web 套接字将状态暴露给外部世界,以便让您直接在您的网络浏览器中监控它们,而无需任何形式的轮询。您甚至不需要终止此线程,因为它是“永远”设计的。
我想到的另一个很好的实时示例是聊天(即时消息)、文档共享(查看实时文件夹更改)、实时多用户文档协作等,以及您可能需要构建的任何内容考虑到实时性。