Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在用户等待时处理大量数据的最佳实践(在Rails中)?_Ruby On Rails_Ruby On Rails 3_Delayed Job_Long Running Processes - Fatal编程技术网

Ruby on rails 在用户等待时处理大量数据的最佳实践(在Rails中)?

Ruby on rails 在用户等待时处理大量数据的最佳实践(在Rails中)?,ruby-on-rails,ruby-on-rails-3,delayed-job,long-running-processes,Ruby On Rails,Ruby On Rails 3,Delayed Job,Long Running Processes,我有一个bookmarklet,当使用它时,它会将当前浏览器页面上的所有URL提交给Rails 3应用程序进行处理。在幕后,我用它来检查每个URL是否返回2XX状态码。目前,我通过对Rails服务器的AJAX请求启动这个过程,并在它处理和返回结果时等待。对于一个很小的集合,这是非常快的,但是当URL的数量相当大时,用户最多可以等待10-15秒 我已经考虑过在用户线程之外使用延迟作业来处理这个问题,但这似乎不是一个合适的用例。由于用户需要等到处理完成后才能看到结果,而延迟的作业可能需要5秒钟才能开

我有一个bookmarklet,当使用它时,它会将当前浏览器页面上的所有URL提交给Rails 3应用程序进行处理。在幕后,我用它来检查每个URL是否返回2XX状态码。目前,我通过对Rails服务器的AJAX请求启动这个过程,并在它处理和返回结果时等待。对于一个很小的集合,这是非常快的,但是当URL的数量相当大时,用户最多可以等待10-15秒

我已经考虑过在用户线程之外使用延迟作业来处理这个问题,但这似乎不是一个合适的用例。由于用户需要等到处理完成后才能看到结果,而延迟的作业可能需要5秒钟才能开始,因此我不能保证处理会尽快进行。不幸的是,在这种情况下,这种等待时间是不可接受的

理想情况下,我认为应该这样做:

  • 用户点击书签
  • 数据被发送到服务器进行处理
  • 旋转线程进行处理时,会立即返回等待页面
  • 等待页面通过ajax定期轮询处理结果并更新等待页面(例如:“567个URL中的4个已处理…”)
  • 等待页面将在结果准备就绪后更新
一些额外的细节:

  • 我使用Heroku(长时间运行的进程在30秒后被杀死)
  • 登录用户和匿名用户都可以使用此功能

这是一种典型的方法,还是有更好的方法?我应该在处理过程中启动自己的线程外处理来更新数据库,还是有类似延迟作业的东西可以用于此(在Heroku上也可以使用)?如果你能向正确的方向努力,我将不胜感激。

我认为你的后一个想法最有意义。我只是将每个url检查的处理卸载到它自己的线程中(因此所有url检查都是并发运行的——无论如何,这应该比顺序检查快得多)。当每一个线程完成时,它会更新数据库(确保线程不会踩到彼此的写操作)。AJAX端点——正如您所说,您可以在客户端定期进行轮询——将获取并返回数据库中已完成进程的计数。这是一种非常简单的方法,我认为不需要任何额外的组件。

幸运的是,Typhous并行处理URL,因此比串行处理要快得多。它还提供了一个on_完整回调,我可以挂接到其中。(目前,我正在使用它将结果缓存到memcache中。)我想我不能理解的是:如何将这些数据附加到用户?尤其是如果用户是匿名的。我想是吧?如果是匿名用户,我不希望这些数据存储在我的数据库中。看起来系统已经安装好了。只需在typhous on_complete处理程序中设置的密钥中添加会话ID。然后在基于会话id访问这些memcache密钥的轮询端点中,可以(一旦所有内容都被处理并返回给用户)从数据库中清除相关密钥。但是根据你的评论,我相信你已经考虑过了,并且对此有一些问题——但我并没有真正理解这个问题是什么。啊,我想我只是没有想到直接使用memcache作为完成结果数据的临时存储。我现在只使用它来缓存单个url爬网的结果。(与特定用户无关)但你说得对,我完全可以使用memcache临时存储特定用户请求的完整结果。这样,它就不会为匿名用户破坏数据库,因为它不是关键数据。(它将为注册用户持续保存。)好主意。谢谢你帮我想清楚。你最后做了什么?@Ari我已经很久没有做过这件事了,但总的来说,我使用了一个后台处理器(我今天会使用sidekiq)和一个跟踪进度的状态机。然后我在前端使用xhr进行了民意调查,直到状态“完成”或您需要的任何东西。谢谢。所以我猜Thread.new不能自己工作?