这种Rails多线程方法有什么问题吗?

时间:2022-11-09 20:41:46

I'm fighting with Rails and polling really long jobs (30 minutes and so alike...) I've read many other options like using BackgroundRb or Background Job, but for now I've tried something like this :

我正在与Rails战斗并且轮询很长时间的工作(30分钟等等......)我已经阅读了很多其他选项,例如使用BackgroundRb或后台工作,但是现在我尝试过这样的事情:

class HeavyController < ApplicationController    

def poll
  render text: $longlog
end

def longjob
  Thread.new do 
    tasks.each do |j|
      # here's the job proc, CPU & IO intense
      $longlog << "some message about current job status"
    end   
  end
end

end

on client's side I've wrote simple javascript setTimeout that calls repeatedly $.get('poll_log', {...}) and sets .html() of a dialog showing progress.

在客户端我编写了简单的javascript setTimeout,它反复调用$ .get('poll_log',{...})并设置显示进度的对话框的.html()。

besides of using Ruby's global $longlog (which is obviously wrong), what other problems may arise from this approach ? Should I leave it for unlocking multithreaded flavour of WEBRick ? But what if WEBRick decides to kill long-lasting task for timeout reasons? May WEBRick in default configuration kill thread from my approach ? My application wouldn't be used intensively by the users, definitely not requiring processing thousands of request per second. Rather I need to have opportunity to check status of background job anytime I click "Show status" button on webpage... (Long job may be fired only by admin account)....

除了使用Ruby的全局$ longlog(这显然是错误的)之外,这种方法可能会产生哪些其他问题?我是否应该将其用于解锁WEBRick的多线程风味?但是,如果WEBRick因超时原因决定终止长期任务呢?可以从我的方法中使用默认配置杀死线程吗?我的应用程序不会被用户强烈使用,绝对不需要每秒处理数千个请求。相反,当我点击网页上的“显示状态”按钮时,我需要有机会检查后台作业的状态...(长时间的工作可能只能由管理员帐户解雇)....

Thanks in advance for some directions...

提前感谢某些方向......

2 个解决方案

#1


3  

You shouldn't run anything on Webrick in production, it's only suitable for local testing. Your thread solution will not work if you run multiple instances of your application, it would only work if your next request hits the same instance.

你不应该在生产中在Webrick上运行任何东西,它只适用于本地测试。如果您运行应用程序的多个实例,则您的线程解决方案将无法工作,只有当您的下一个请求命中同一个实例时,它才会起作用。

Just put that thing into a background job processor. They are quite easy to set up. BackgroundRb is old and pretty much dead. The choices these days are Sidekiq, Resque, DelayedJob and Backburner. Delayed job is probably the easiest to get started with, since it doesn't require any additional services.

只需将该东西放入后台作业处理器即可。它们很容易设置。 BackgroundRb很老了,几乎死了。这些天的选择是Sidekiq,Resque,DelayedJob和Backburner。延迟工作可能是最容易上手的,因为它不需要任何额外的服务。

The background job should probably publish it's "log" to the database, something like LongjobLog.create(:message => "did stuff") and then your Javascript poll thing should request items where id > last_received_id to only get the new lines.

后台作业应该可以将它的“log”发布到数据库,比如LongjobLog.create(:message =>“does stuff”),然后你的Javascript poll事件应该请求id> last_received_id的项目才能获得新行。

#2


0  

In my experience using gems like DelayedJob works very well. You find the link helpful. Do you have workers processing your background job? If not that's something you can easily do in the terminal and watch your background job process. I do to see what is actually happening and for understanding what's going on.

根据我使用像DelayedJob这样的宝石的经验非常好。您会发现该链接很有用。你有工人处理你的后台工作吗?如果不是这样,您可以在终端轻松完成并观察后台工作流程。我确实看到了实际发生的事情以及了解发生了什么。

#1


3  

You shouldn't run anything on Webrick in production, it's only suitable for local testing. Your thread solution will not work if you run multiple instances of your application, it would only work if your next request hits the same instance.

你不应该在生产中在Webrick上运行任何东西,它只适用于本地测试。如果您运行应用程序的多个实例,则您的线程解决方案将无法工作,只有当您的下一个请求命中同一个实例时,它才会起作用。

Just put that thing into a background job processor. They are quite easy to set up. BackgroundRb is old and pretty much dead. The choices these days are Sidekiq, Resque, DelayedJob and Backburner. Delayed job is probably the easiest to get started with, since it doesn't require any additional services.

只需将该东西放入后台作业处理器即可。它们很容易设置。 BackgroundRb很老了,几乎死了。这些天的选择是Sidekiq,Resque,DelayedJob和Backburner。延迟工作可能是最容易上手的,因为它不需要任何额外的服务。

The background job should probably publish it's "log" to the database, something like LongjobLog.create(:message => "did stuff") and then your Javascript poll thing should request items where id > last_received_id to only get the new lines.

后台作业应该可以将它的“log”发布到数据库,比如LongjobLog.create(:message =>“does stuff”),然后你的Javascript poll事件应该请求id> last_received_id的项目才能获得新行。

#2


0  

In my experience using gems like DelayedJob works very well. You find the link helpful. Do you have workers processing your background job? If not that's something you can easily do in the terminal and watch your background job process. I do to see what is actually happening and for understanding what's going on.

根据我使用像DelayedJob这样的宝石的经验非常好。您会发现该链接很有用。你有工人处理你的后台工作吗?如果不是这样,您可以在终端轻松完成并观察后台工作流程。我确实看到了实际发生的事情以及了解发生了什么。