When a new resource is created and it needs to do some lengthy processing before the resource is ready, how do I send that processing away into the background where it won't hold up the current request or other traffic to my web-app?
当一个新的资源被创建,并且它需要在资源准备好之前进行一些长时间的处理时,我如何将处理发送到后台,在后台它不会阻塞当前的请求或其他流量到我的web应用程序?
in my model:
在我的模型:
class User < ActiveRecord::Base
after_save :background_check
protected
def background_check
# check through a list of 10000000000001 mil different
# databases that takes approx one hour :)
if( check_for_record_in_www( self.username ) )
# code that is run after the 1 hour process is finished.
user.update_attribute( :has_record )
end
end
end
7 个解决方案
#1
39
You should definitely check out the following Railscasts:
你一定要看看下面的列车:
- http://railscasts.com/episodes/127-rake-in-background
- http://railscasts.com/episodes/127-rake-in-background
- http://railscasts.com/episodes/128-starling-and-workling
- http://railscasts.com/episodes/128-starling-and-workling
- http://railscasts.com/episodes/129-custom-daemon
- http://railscasts.com/episodes/129-custom-daemon
- http://railscasts.com/episodes/366-sidekiq
- http://railscasts.com/episodes/366-sidekiq
They explain how to run background processes in Rails in every possible way (with or without a queue ...)
它们解释了如何在Rails中以各种可能的方式运行后台进程(无论是否有队列…)
#2
7
Start a separate process, which is probably most easily done with system
, prepending a 'nohup' and appending an '&' to the end of the command you pass it. (Make sure the command is just one string argument, not a list of arguments.)
启动一个单独的进程,这可能是最容易完成的系统,在“nohup”之前,并在命令的末尾加上“&”。(确保该命令只是一个字符串参数,而不是一个参数列表。)
There are several reasons you want to do it this way, rather than, say, trying to use threads:
有几个原因你想这样做,而不是尝试使用线程:
-
Ruby's threads can be a bit tricky when it comes to doing I/O; you have to take care that some things you do don't cause the entire process to block.
Ruby的线程在执行I/O时可能有点棘手;你必须注意,你所做的一些事情不会导致整个过程被阻塞。
-
If you run a program with a different name, it's easily identifiable in 'ps', so you don't accidently think it's a FastCGI back-end gone wild or something, and kill it.
如果你运行一个名字不同的程序,它很容易在“ps”中被识别出来,所以你不会不小心地认为它是一个快速cgi后端失控或其他什么东西,然后杀死它。
Really, the process you start should be "deamonized," see the Daemonize class for help.
真的,你开始的过程应该是“去教化”的,见恶魔类求助。
#3
6
I've just been experimenting with the 'delayed_job' gem because it works with the Heroku hosting platform and it was ridiculously easy to setup!!
我刚刚试用了“delayed_job”gem,因为它与Heroku主机平台兼容,安装起来非常简单!
Add gem to Gemfile, bundle install
, rails g delayed_job
, rake db:migrate
Then start a queue handler with;
向Gemfile中添加gem、bundle安装、rails g delayed_job、rake db:迁移并启动队列处理程序;
RAILS_ENV=production script/delayed_job start
Where you have a method call which is your lengthy process i.e
你有一个方法调用它是你冗长的过程
company.send_mail_to_all_users
you change it to;
你改变它;
company.delay.send_mail_to_all_users
Check the full docs on github: https://github.com/collectiveidea/delayed_job
查看github上的完整文档:https://github.com/collectiveidea/delayed_job。
#4
2
you ideally want to use an existing background job server, rather than writing your own. these will typically let you submit a job and give it a unique key; you can then use the key to periodically query the jobserver for the status of your job without blocking your webapp. here is a nice roundup of the various options out there.
理想情况下,您希望使用现有的后台作业服务器,而不是编写自己的后台作业服务器。这些通常会让你提交一个作业并给它一个唯一的密钥;然后,您可以使用密钥定期查询jobserver的状态,而不阻塞您的web应用程序。这里有一个不错的综合选项。
#5
1
I like to use backgroundrb, its nice it allows you to communicate to it during long processes. So you can have status updates in your rails app
我喜欢使用backgrounddrb,它很好,它允许你在漫长的过程中与它交流。所以你可以在你的rails应用中更新状态
#6
1
I think spawn is a great way to fork your process, do some processing in background, and show user just some confirmation that this processing was started.
我认为衍生是一种很好的方法,它可以将你的进程分成多个部分,在后台进行一些处理,并向用户显示这个处理已经开始。
#7
0
What about:
是什么:
def background_check
exec("script/runner check_for_record_in_www.rb #{self.username}") if fork == nil
end
The program "check_for_record_in_www.rb
" will then run in another process and will have access to ActiveRecord, being able to access the database.
然后,程序“check_for_record_in_www.rb”将在另一个进程中运行,并可以访问ActiveRecord,能够访问数据库。
#1
39
You should definitely check out the following Railscasts:
你一定要看看下面的列车:
- http://railscasts.com/episodes/127-rake-in-background
- http://railscasts.com/episodes/127-rake-in-background
- http://railscasts.com/episodes/128-starling-and-workling
- http://railscasts.com/episodes/128-starling-and-workling
- http://railscasts.com/episodes/129-custom-daemon
- http://railscasts.com/episodes/129-custom-daemon
- http://railscasts.com/episodes/366-sidekiq
- http://railscasts.com/episodes/366-sidekiq
They explain how to run background processes in Rails in every possible way (with or without a queue ...)
它们解释了如何在Rails中以各种可能的方式运行后台进程(无论是否有队列…)
#2
7
Start a separate process, which is probably most easily done with system
, prepending a 'nohup' and appending an '&' to the end of the command you pass it. (Make sure the command is just one string argument, not a list of arguments.)
启动一个单独的进程,这可能是最容易完成的系统,在“nohup”之前,并在命令的末尾加上“&”。(确保该命令只是一个字符串参数,而不是一个参数列表。)
There are several reasons you want to do it this way, rather than, say, trying to use threads:
有几个原因你想这样做,而不是尝试使用线程:
-
Ruby's threads can be a bit tricky when it comes to doing I/O; you have to take care that some things you do don't cause the entire process to block.
Ruby的线程在执行I/O时可能有点棘手;你必须注意,你所做的一些事情不会导致整个过程被阻塞。
-
If you run a program with a different name, it's easily identifiable in 'ps', so you don't accidently think it's a FastCGI back-end gone wild or something, and kill it.
如果你运行一个名字不同的程序,它很容易在“ps”中被识别出来,所以你不会不小心地认为它是一个快速cgi后端失控或其他什么东西,然后杀死它。
Really, the process you start should be "deamonized," see the Daemonize class for help.
真的,你开始的过程应该是“去教化”的,见恶魔类求助。
#3
6
I've just been experimenting with the 'delayed_job' gem because it works with the Heroku hosting platform and it was ridiculously easy to setup!!
我刚刚试用了“delayed_job”gem,因为它与Heroku主机平台兼容,安装起来非常简单!
Add gem to Gemfile, bundle install
, rails g delayed_job
, rake db:migrate
Then start a queue handler with;
向Gemfile中添加gem、bundle安装、rails g delayed_job、rake db:迁移并启动队列处理程序;
RAILS_ENV=production script/delayed_job start
Where you have a method call which is your lengthy process i.e
你有一个方法调用它是你冗长的过程
company.send_mail_to_all_users
you change it to;
你改变它;
company.delay.send_mail_to_all_users
Check the full docs on github: https://github.com/collectiveidea/delayed_job
查看github上的完整文档:https://github.com/collectiveidea/delayed_job。
#4
2
you ideally want to use an existing background job server, rather than writing your own. these will typically let you submit a job and give it a unique key; you can then use the key to periodically query the jobserver for the status of your job without blocking your webapp. here is a nice roundup of the various options out there.
理想情况下,您希望使用现有的后台作业服务器,而不是编写自己的后台作业服务器。这些通常会让你提交一个作业并给它一个唯一的密钥;然后,您可以使用密钥定期查询jobserver的状态,而不阻塞您的web应用程序。这里有一个不错的综合选项。
#5
1
I like to use backgroundrb, its nice it allows you to communicate to it during long processes. So you can have status updates in your rails app
我喜欢使用backgrounddrb,它很好,它允许你在漫长的过程中与它交流。所以你可以在你的rails应用中更新状态
#6
1
I think spawn is a great way to fork your process, do some processing in background, and show user just some confirmation that this processing was started.
我认为衍生是一种很好的方法,它可以将你的进程分成多个部分,在后台进行一些处理,并向用户显示这个处理已经开始。
#7
0
What about:
是什么:
def background_check
exec("script/runner check_for_record_in_www.rb #{self.username}") if fork == nil
end
The program "check_for_record_in_www.rb
" will then run in another process and will have access to ActiveRecord, being able to access the database.
然后,程序“check_for_record_in_www.rb”将在另一个进程中运行,并可以访问ActiveRecord,能够访问数据库。