我有一个 wasm 进程(从 C++ 编译),用于处理 Web 应用程序中的数据。假设必要的代码如下所示:
std::vector<JSONObject> data
for (size_t i = 0; i < data.size(); i++)
{
process_data(data[i]);
if (i % 1000 == 0) {
bool is_cancelled = check_if_cancelled();
if (is_cancelled) {
break;
}
}
}
此代码基本上类似于 SQL 查询界面“运行/处理查询”:
但是,查询可能需要几分钟来运行/处理,并且用户可以在任何给定时间取消他们的查询。取消过程将发生在正常的 javascript/web 应用程序中,在运行 wasm 的 service Worker 之外。
那么我的问题是什么是我们如何知道用户已单击“取消”按钮并将其传达给 wasm 进程以便知道该进程已被取消以便它可以退出的示例?使用worker.terminate()
不是一种选择,因为我们需要为此保留所有加载的数据,worker
而不能仅仅杀死该工作人员(它需要使用其存储的数据保持活动状态,因此可以运行另一个查询......)。
在 javascript 和 worker/wasm/c++ 应用程序之间进行通信的示例方式是什么,以便我们知道何时退出以及如何正确执行?
此外,让我们假设一个典型的查询需要 60 秒来运行并使用 cpp/wasm 在浏览器中处理 500MB 的数据。
更新:我认为根据一些研究(以及下面的初始答案/评论)和一些反馈,这里有以下可能的解决方案:
使用两个 worker,一个 worker 存储数据,另一个 worker 处理数据。通过这种方式可以终止处理工作者,并且数据将始终保留。可行的?不是真的,因为每当它启动时,将超过 500MB 的数据复制到 webworker 会花费太多时间。这可以(以前)使用SharedArrayBuffer 完成,但由于一些安全问题,它的支持现在非常有限/不存在。太糟糕了,因为如果支持,这似乎是迄今为止最好的解决方案......
使用Emterpreter和使用emscripten_sleep_with_yield
. 可行的?不,在使用 Emterpreter 时会破坏性能(在上面的文档中提到过),并使所有查询速度降低约 4-6 倍。
始终运行第二个工作程序,并且在 UI 中只显示最新的。可行的?不,如果它不是共享数据结构并且数据大小为 500MB x 2 = 1GB(在现代桌面浏览器/计算机中运行时,500MB 似乎是一个大但可接受的大小),则可能会遇到很多 OOM 错误。
使用对服务器的 API 调用来存储状态并检查查询是否被取消。可行的?是的,尽管从每个正在运行的查询中每秒对网络请求进行长时间轮询似乎很笨拙。
使用增量解析方法,一次只解析一行。可行的?是的,但也需要大量重写解析函数,以便每个函数都支持这一点(实际的数据解析在几个函数中处理——过滤、搜索、计算、分组、排序等。
使用 IndexedDB 并将状态存储在 javascript 中。在 WASM 中分配一块内存,然后将其指针返回给 JavaScript。然后在那里读取数据库并填充指针。然后用 C++ 处理你的数据。可行的?不确定,尽管如果可以实施,这似乎是最佳解决方案。
[还要别的吗?]
在赏金中,我想知道三件事:
如果以上六项分析似乎普遍有效?
我还缺少其他(也许更好)的方法吗?
任何人都可以展示一个非常基本的例子#6 - 如果可能并且跨浏览器工作,这似乎是最好的解决方案。
Qyouu
蓝山帝景
相关分类