Active Job: Difference between revisions
No edit summary |
|||
Line 16: | Line 16: | ||
*Active Job Async Job | *Active Job Async Job | ||
*Active Job Inline[http://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html] | *Active Job Inline[http://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html] | ||
=='''How to use <ref>http://guides.rubyonrails.org/active_job_basics.html</ref>'''== | |||
This section will guide to creating a job and and how to enqueuing the job. <ref> Rails Guides [http://guides.rubyonrails.org/active_job_basics.html “Active Job Basics” 2014] </ref> <br> | |||
=== Download === | |||
Active Job can be installed with latest version using RubyGems: | |||
<pre> | |||
$ gem install activejob | |||
</pre> | |||
[https://github.com/rails/rails/tree/master/activejob Souce code of Active Job] available on GitHub, as part of Rails.<ref> GitHub [https://github.com/rails/rails/tree/master/activejob “Active Job -- Make work happen later” 2015] </ref> | |||
=== Create a Job === | |||
In Active Job, a process which is inserted in a queue and waiting for carry out is called “Job”. It’s possible to generate a Job using the Generator provided by Rails. The following will create a job in app/jobs, with the name “update_wiki”.<br> | |||
<pre> | |||
$ bin/rails generate job update_wiki | |||
invoke test_unit | |||
create test/jobs/update_wiki_job_test.rb | |||
create app/jobs/update_wiki_job.rb | |||
</pre> | |||
You can also create a job that will run on a specific queue:<br> | |||
<pre> | |||
$ bin/rails generate job update_wiki --queue urgent | |||
</pre> | |||
You could create your own file inside of app/jobs, without using a generator. In Rails 4.2 an ActiveJob inherits from ActiveJob::Base. In Rails 5.0 this behavior has changed to now inherit from ApplicationJob. When upgrading from Rails 4.2 to Rails 5.0 you need to create an application_job.rb file in app/jobs/ and add the following content:<ref> Rails Guides [http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-4-1-to-rails-4-2 “A Guide for Upgrading Ruby on Rails” 2015] </ref> | |||
<pre> | |||
class ApplicationJob < ActiveJob::Base | |||
end | |||
</pre> | |||
In Rails 4.2 a Job class looks like: | |||
<pre> | |||
class UpdateWikiJob < ActiveJob::Base | |||
queue_as :default | |||
def perform(*wiki) | |||
# Do something later | |||
wiki.update_contents | |||
end | |||
end | |||
</pre> | |||
There is a perform method which is called when the job was first enqueued. You can define perform with as many arguments as you want. <br> | |||
=== Adding a Job to the queue === | |||
If you wish your Job be processed as soon as the queuing system is free, you can enqueue a Job like: | |||
<pre> | |||
UpdateWikiJob.perform_later wiki | |||
</pre> | |||
Or you can add a Job be performed tomorrow at noon: | |||
<pre> | |||
UpdateWikiJob.set(wait_until: Date.tomorrow.noon).perform_later(wiki) | |||
</pre> | |||
If you want your Job be performed a week from now, some queueing backends allow you to set a delay time. | |||
<pre> | |||
UpdateWikiJob.set(wait: 1.week).perform_later(wiki) | |||
</pre> | |||
=== Execution of Job === | |||
Active Job has built-in adapters for multiple queueing backends ([https://github.com/mperham/sidekiq/wiki Sidekiq], [https://github.com/resque/resque Resque], [https://github.com/collectiveidea/delayed_job Delayed Job] and [http://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters.html others]).<ref> Rails Guides [http://guides.rubyonrails.org/active_job_basics.html “Active Job Basics” 2014] </ref> If no adapter is set, the job is immediately executed.<br> | |||
You can set your queueing backend at: /config/application.rb, in this example we use the Sidekiq. | |||
<pre> | |||
module YourApp | |||
class Application < Rails::Application | |||
# Be sure to have the adapter's gem in your Gemfile and follow | |||
# the adapter's specific installation and deployment instructions. | |||
config.active_job.queue_adapter = :sidekiq | |||
end | |||
end | |||
</pre> | |||
=== Play with Queues === | |||
Active Job allows to schedule the job to be processed on a specific queue, this became helpful as common adapters support multiple queues. | |||
<pre> | |||
class UpdateWikiJob < ActiveJob::Base | |||
queue_as :low_priority | |||
#.... | |||
end | |||
</pre> | |||
You can prefix the queue name for all your jobs using config.active_job.queue_name_prefixin application.rb: | |||
<pre> | |||
# config/application.rb | |||
module YourApp | |||
class Application < Rails::Application | |||
config.active_job.queue_name_prefix = Rails.env | |||
end | |||
end | |||
# app/jobs/guests_cleanup.rb | |||
class UpdateWikiJob < ActiveJob::Base | |||
queue_as :low_priority | |||
#.... | |||
end | |||
# Now your job will run on queue production_low_priority on your | |||
# production environment and on staging_low_priority on your staging | |||
# environment | |||
</pre> | |||
The default queue name prefix delimiter is '_'. This can be changed by setting config.active_job.queue_name_delimiter in application.rb: | |||
<pre> | |||
# config/application.rb | |||
module YourApp | |||
class Application < Rails::Application | |||
config.active_job.queue_name_prefix = Rails.env | |||
config.active_job.queue_name_delimiter = '.' | |||
end | |||
end | |||
# app/jobs/guests_cleanup.rb | |||
class UpdateWikiJob < ActiveJob::Base | |||
queue_as :low_priority | |||
#.... | |||
end | |||
# Now your job will run on queue production.low_priority on your | |||
# production environment and on staging.low_priority on your staging | |||
# environment | |||
</pre> | |||
If you want more control on what queue a job will be run you can pass a :queue option to #set: | |||
<pre> | |||
MyJob.set(queue: :another_queue).perform_later(record) | |||
</pre> | |||
To control the queue from the job level you can pass a block to #queue_as. The block will be executed in the job context (so you can access self.arguments) and you must return the queue name: | |||
<pre> | |||
class ProcessVideoJob < ActiveJob::Base | |||
queue_as do | |||
video = self.arguments.first | |||
if video.owner.premium? | |||
:premium_videojobs | |||
else | |||
:videojobs | |||
end | |||
end | |||
def perform(video) | |||
# do process video | |||
end | |||
end | |||
ProcessVideoJob.perform_later(Video.last) | |||
</pre> | |||
All the code snippets are referred from the source:<ref> Rails Guides [http://guides.rubyonrails.org/active_job_basics.html “Active Job Basics” 2014] </ref> |
Revision as of 14:29, 31 January 2016
Introduction
Active Job is a framework help developers writing codes and run them on the background automatically under different scenarios. Jobs can vary from schedule newsletter, follow-up emails to database housekeeping. It’s a interface that adapts different queueing backends like Backburner[1], Delayed Job[2], Qu[3] and so on. [4] Overall, Active Job is a interface which you can work with common queues.
Active Job adapters[5]
- Backburner[6]
- Delayed Job[7]
- Qu[8]
- Que[9]
- queue_classic[10]
- Resque 1.x[11]
- Sidekiq[12]
- Sneakers[13]
- Sucker Punch[14]
- Active Job Async Job
- Active Job Inline[15]
How to use <ref>http://guides.rubyonrails.org/active_job_basics.html</ref>
This section will guide to creating a job and and how to enqueuing the job. <ref> Rails Guides “Active Job Basics” 2014 </ref>
Download
Active Job can be installed with latest version using RubyGems:
$ gem install activejob
Souce code of Active Job available on GitHub, as part of Rails.<ref> GitHub “Active Job -- Make work happen later” 2015 </ref>
Create a Job
In Active Job, a process which is inserted in a queue and waiting for carry out is called “Job”. It’s possible to generate a Job using the Generator provided by Rails. The following will create a job in app/jobs, with the name “update_wiki”.
$ bin/rails generate job update_wiki invoke test_unit create test/jobs/update_wiki_job_test.rb create app/jobs/update_wiki_job.rb
You can also create a job that will run on a specific queue:
$ bin/rails generate job update_wiki --queue urgent
You could create your own file inside of app/jobs, without using a generator. In Rails 4.2 an ActiveJob inherits from ActiveJob::Base. In Rails 5.0 this behavior has changed to now inherit from ApplicationJob. When upgrading from Rails 4.2 to Rails 5.0 you need to create an application_job.rb file in app/jobs/ and add the following content:<ref> Rails Guides “A Guide for Upgrading Ruby on Rails” 2015 </ref>
class ApplicationJob < ActiveJob::Base end
In Rails 4.2 a Job class looks like:
class UpdateWikiJob < ActiveJob::Base queue_as :default def perform(*wiki) # Do something later wiki.update_contents end end
There is a perform method which is called when the job was first enqueued. You can define perform with as many arguments as you want.
Adding a Job to the queue
If you wish your Job be processed as soon as the queuing system is free, you can enqueue a Job like:
UpdateWikiJob.perform_later wiki
Or you can add a Job be performed tomorrow at noon:
UpdateWikiJob.set(wait_until: Date.tomorrow.noon).perform_later(wiki)
If you want your Job be performed a week from now, some queueing backends allow you to set a delay time.
UpdateWikiJob.set(wait: 1.week).perform_later(wiki)
Execution of Job
Active Job has built-in adapters for multiple queueing backends (Sidekiq, Resque, Delayed Job and others).<ref> Rails Guides “Active Job Basics” 2014 </ref> If no adapter is set, the job is immediately executed.
You can set your queueing backend at: /config/application.rb, in this example we use the Sidekiq.
module YourApp class Application < Rails::Application # Be sure to have the adapter's gem in your Gemfile and follow # the adapter's specific installation and deployment instructions. config.active_job.queue_adapter = :sidekiq end end
Play with Queues
Active Job allows to schedule the job to be processed on a specific queue, this became helpful as common adapters support multiple queues.
class UpdateWikiJob < ActiveJob::Base queue_as :low_priority #.... end
You can prefix the queue name for all your jobs using config.active_job.queue_name_prefixin application.rb:
# config/application.rb module YourApp class Application < Rails::Application config.active_job.queue_name_prefix = Rails.env end end # app/jobs/guests_cleanup.rb class UpdateWikiJob < ActiveJob::Base queue_as :low_priority #.... end # Now your job will run on queue production_low_priority on your # production environment and on staging_low_priority on your staging # environment
The default queue name prefix delimiter is '_'. This can be changed by setting config.active_job.queue_name_delimiter in application.rb:
# config/application.rb module YourApp class Application < Rails::Application config.active_job.queue_name_prefix = Rails.env config.active_job.queue_name_delimiter = '.' end end # app/jobs/guests_cleanup.rb class UpdateWikiJob < ActiveJob::Base queue_as :low_priority #.... end # Now your job will run on queue production.low_priority on your # production environment and on staging.low_priority on your staging # environment
If you want more control on what queue a job will be run you can pass a :queue option to #set:
MyJob.set(queue: :another_queue).perform_later(record)
To control the queue from the job level you can pass a block to #queue_as. The block will be executed in the job context (so you can access self.arguments) and you must return the queue name:
class ProcessVideoJob < ActiveJob::Base queue_as do video = self.arguments.first if video.owner.premium? :premium_videojobs else :videojobs end end def perform(video) # do process video end end ProcessVideoJob.perform_later(Video.last)
All the code snippets are referred from the source:<ref> Rails Guides “Active Job Basics” 2014 </ref>