在ActiveJob和Controller之间共享数据

每n秒应用程序请求一个远程JSON文件,该文件为交易系统中的证券提供实时价格。 JSON包含我需要的数据( marketdata )和具有当前dataversionversionseqnum )的块。

现在我使用ActionController::Live (在客户端使用EventSource )将更新的数据推送到浏览器。 所有操作都在一种方法中完成:

  • 开通SSE连接;
  • 形成动态网址;
  • 从远程服务器提取新数据;
  • 比较/重新分配seqnum值;
  • 如果需要更新数据库。
  • 所以我现在的目标是分离拉动和更新数据库( ActiveJob )并将更新的值推送到浏览器( ActionController::Live )。 要做到这一点,我需要:

  • 要么在服务器端seqnumversion某处存储以在控制器和后台作业之间共享;
  • 或监视数据库以获取updated_at字段中的最新更改。
  • 所以基本上我有两个问题:

  • 上述两种选择之间更有效率吗?还有其他好的方法吗?
  • (如果第一个人有权存在)如何实施这种方法?

  • 考虑到你可能有多个轨道进程运行的事实,我相信你让activejob以某种方式直接与轨道控制器交谈变得相当困难。

    Defintely存储seqnumversion ,在任何情况下,我都不会依赖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端点,这次是在你的迷你应用程序中)到你的所有迷你应用程序实例,然后它们会发送它们给你的客户。

    通过这种方式,您不会使主服务器过载,而只会使这些小型节点发生本地故障 (这是一个很大的优势,而不是大的系统停机)。

    链接地址: http://www.djcxy.com/p/26703.html

    上一篇: Share data between ActiveJob and Controller

    下一篇: atom.io Laravel autoprediction woes