例如,考虑到您可能有多个 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
无需轮询
如果你想要一个不涉及轮询的选项,我相信你只能选择 websockets。但是,您有一个更有效的选择:
创建一个客户端将轮询的迷你应用程序(evenmachine/sinatra/something light)(您可以通过您的主应用程序将其分发到此迷你应用程序的不同节点),此应用程序的目的只是重新路由来自您的主应用程序的消息应用到轮询客户端。
现在,您可以为您的主应用程序创建一个内部 API 端点,该端点仅供延迟作业使用。延迟作业只有在注意到获取的 JSON 相对于当前存储的 JSON 实际更新时才会到达此端点。如果是这种情况,它将到达您的主应用 API 端点,该端点会向您的所有迷你应用实例发送一条消息(同样,可能是通过 HTTP API 端点,这次是在您的迷你应用上),然后再发送它们给你的客户。
通过这种方式,您不会使主服务器超载,而只会使这些迷你节点超载,这些迷你节点可能会出现局部中断(这是一个很大的优势,而不是出现大的系统中断)。