pot*_*hin 7 ruby-on-rails ruby-on-rails-4 ruby-on-rails-4.2 rails-activejob
每隔n秒,应用程序就会请求一个远程JSON文件,该文件为交易系统中的证券提供实时价格.JSON有一个包含我需要的数据的块(marketdata)和一个包含当前dataversion(version和seqnum)的块.
现在我使用ActionController::Live(EventSource在客户端)将更新的数据推送到浏览器.所有操作都在一个方法内完成:
seqnum价值;所以我现在的目标是ActiveJob通过将更新的值推送到浏览器(ActionController::Live)来分离拉取和更新数据库().要做到这一点,我需要:
seqnum与version控制器和后台作业之间共享;updated_at字段中的最新更改.所以基本上我有两个问题:
例如,考虑到您可能运行多个 Rails 进程,我相信您很难让 activejob 以某种方式直接与 Rails 控制器对话。
绝对存储seqnum和version,在任何情况下我都不会依赖updated_at,它太容易随机更新,因此最终在没有任何真正原因的情况下向客户发送内容。同样在这种情况下,它们似乎是非常可靠的字段来指出文件是否已更新。
话虽如此,您想以ActionController::Live某种方式“发出信号”,恐怕在这里轮询是您唯一的选择,除非在您的客户端有一个特定的时刻需要知道文件是否已更新,在这种情况下你可能想使用 websockets 或类似的东西。
所以,像
cached_request = YourCachedRequest.latest # Assuming it returns a single record
updated = true
loop do
if updated
updated = false
response.stream.write cached_request.serialize_in_some_way
end
current_version = cached_request.version # use seqnum too if you need
cached_request = cached_request.reload
updated = true if cached_request.version > current_version
sleep 20.0
end
Run Code Online (Sandbox Code Playgroud)
如果你想要一个不涉及轮询的选项,我相信你只能选择网络套接字。但是您有一个更有效的选择:
创建一个迷你应用程序(evenmachine/sinatra/something light),客户端将在其中轮询(您可以通过主应用程序将其分发到该迷你应用程序的不同节点),此应用程序的目的只是重新路由来自主应用程序的消息应用于投票客户端。
现在,您可以为主应用程序创建一个内部 API 端点,该端点仅由延迟作业使用。仅当延迟作业注意到获取的 JSON 相对于当前存储的 JSON 实际上已更新时,才会命中此端点。如果是这种情况,它将命中您的主应用程序 API 端点,该端点又会向所有迷你应用程序实例发送一条消息(同样,可能通过 HTTP API 端点,这次是在您的迷你应用程序上),后者又将向它们发送消息给您的客户。
通过这种方式,您不会使主服务器超载,而只会使这些可能发生局部中断的迷你节点超载(这是一个很大的优势,而不是造成大的系统中断)。
| 归档时间: |
|
| 查看次数: |
352 次 |
| 最近记录: |