如何在主线程和 Web worker 之间共享 pouchDB



在Web应用程序中,使用pouchDB,我有一个运行缓慢的函数,该函数通过更新数据库中的文档来完成。我想将其从主 UI 线程移动到 Web 工作者中。但是,我们还有很多其他使用 pouchDB 的代码仍在主线程中(例如,change事件侦听器,以及处理其他文档的代码(。(作为参考,数据库大小约为 100MB;使用 Vue2 是这样,一般来说,UI 可以在数据更改时更新。

这就是我似乎立即解开卡住的地方:

  • 共享内存基本上已经耗尽,因为默认情况下所有浏览器都禁用它
  • 即使不是,pouchDB 也是一个类,不能转移(?
  • 将所有
  • 数据库代码(包括更改处理程序(隔离到一个 Web worker 中是一个巨大的重构;然后我们仍然会遇到必须将大量数据传入和传出该 Web Worker 的问题。
  • 将所有使用数据的代码也移动到 Web worker 中,并且只是让 UI 线程来回传递消息,这是一个更大的重构,我还没有考虑过它会如何干扰 Vue。

这似乎让我们有两个极端的选择。要么从头开始重写整个应用程序,可能会删除 Vue,要么只是在 Web worker 中进行缓慢、复杂的计算,然后让它传回结果,并继续在主 UI 线程中执行db.put()

这真的是全有还是全无的情况?是否有任何允许与 Web 工作者合作的 PouchDB "技巧",如果是这样,我们是否需要实现锁定?

你错过了一个选项,我会在你的情况下选择。编写一个简单的适配器,允许工作线程代码通过消息查询主线程中的数据库。获取您的数据,在工作人员中处理它并将其发回。

您只需要在工作线程中"包装"所需的方法。我建议在worker中编写一个或一组异步的函数,以使代码可读。

您无需担心传递的数据量。序列化和反序列化非常快,传输基本上是memcpy的,因此不需要任何合理的时间。

我找到了这个适配器插件,我想它算作我所追求的"PouchDB 技巧":https://github.com/pouchdb-community/worker-pouch

添加它很简单(见下文(,并且已经在生产中使用了 6-7 周,并且似乎已经解决了我们看到的问题。(我说看起来,因为很难看到它有任何影响,而且我们没有很好的方法来重现用户看到的减速问题。

const PouchDB = require('pouchdb-browser').default
const pouchdbWorker = require('worker-pouch')
PouchDB.adapter('worker', pouchdbWorker)

真正的代码是这样的,但usePouchDBWorker一直保持true

const PouchDB = require('pouchdb-browser').default
// const pouchdbDebug = require('pouchdb-debug')
if (usePouchDBWorker) {
const pouchdbWorker = require('worker-pouch')
PouchDB.adapter('worker', pouchdbWorker)
}

此代码用于Web应用程序和Electron构建。Web 应用程序从未与较旧的 Web 浏览器一起使用,因此请阅读 github 站点,如果这可能是您自己的用例的问题。

最新更新