【问题标题】:Rails concurrent requestsRails 并发请求
【发布时间】:2015-02-16 07:44:59
【问题描述】:

所以我有一个解析长 json 文件的 rails 应用程序 - 在此期间它将请求发送到外部 API,这似乎需要很长时间。我的问题是,将每个请求放入单独的线程以加快速度是否简单?我不明白为什么我不能说 3 或 4 个线程同时运行发送请求......我看到的唯一问题是当前如果在解析结束时出现任何错误,该方法会显示一个错误页面 - 并且这可能不会发生,因为其他线程可能仍在运行? .. 最终我想把这个方法变成一个 rake 任务并使用一个呈现 html 页面的 cron 作业来运行它,这样应该更好吗?

def load_movies
 @errors = []
 movie_list = get_data

 movie_list.first(50).each do |movie_data|
 ------------ Thread.new do -----------
  movie = Movie.new
  movie.construct_movie movie_data

  if !movie.valid?
    @errors << movie
  else
   movie.save
  end
  ----------- end thread ------------
  unless @errors.count > 0
  redirect_to root_path
end
end

是不是就如上面那样简单,它会跑开多个线程来发送请求(可以假设在construct_movie中

【问题讨论】:

  • 这听起来像是后台作业的完美示例。您是否考虑过使用DelayedJobsSidekiq
  • 我确实看过 sidekiq - 我的问题是它最终重定向到错误页面,我认为我做不到。
  • 您可以在数据库中收集错误并在所有工作完成后将它们显示给用户。
  • 我如何检测所有工作何时完成然后做某事?
  • 让每个作业将其状态报告回数据库中的模型。如果返回的工作数量等于创建的工作数量,显然所有工作都已完成......

标签: ruby-on-rails ruby multithreading


【解决方案1】:

可以这样做,是的。我已经做到了,是的。

如果您使用 ActiveRecord,您可能会在多线程使用 ActiveRecord 时遇到一些问题。对于在 ruby​​ 中做多线程的事情,我推荐 concurrent-ruby gem,它提供线程池和更高级别的抽象,如 Futures。 https://github.com/ruby-concurrency/concurrent-ruby

可以做到这一点,虽然,是的,它可能会变得很棘手——如果后台作业队列有效,那么这对您来说可能是一个不那么重新发明轮子的解决方案。无论是后台作业队列 还是 线程,您都必须弄清楚如何显示“结果”——尽管使用直接线程方法,我猜您的请求可以等待所有线程并且他们的结果,在显示结果之前(是的,我也这样做了)。这可能会导致请求运行缓慢(您可能希望与 puma 或乘客企业一起部署以避免阻塞您的整个应用程序进程)。

根据我自己做类似事情的经验,我没有一个简单的答案,我想无论你走哪条路都会遇到一些挑战。如果你能找到一种方法让后台作业队列工作,我认为这通常会给你比直接在应用程序进程中创建线程更少的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多