aboutsummaryrefslogtreecommitdiffstats
path: root/activejob/README.md
blob: 56562d870bb4b234964b51cf85628c3efe5d7e8a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# Active Job -- Make work happen later

Active Job is a framework for declaring jobs and making them run on a variety
of queueing backends. These jobs can be everything from regularly scheduled
clean-ups, to billing charges, to mailings. Anything that can be chopped up into
small units of work and run in parallel, really.

It also serves as the backend for Action Mailer's #deliver_later functionality
that makes it easy to turn any mailing into a job for running later. That's
one of the most common jobs in a modern web application: sending emails outside
of the request-response cycle, so the user doesn't have to wait on it.

The main point is to ensure that all Rails apps will have a job infrastructure
in place, even if it's in the form of an "immediate runner". We can then have
framework features and other gems build on top of that, without having to worry
about API differences between Delayed Job and Resque. Picking your queuing
backend becomes more of an operational concern, then. And you'll be able to
switch between them without having to rewrite your jobs.


## Usage

To learn how to use your preferred queueing backend see its adapter
documentation at
[ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).

Declare a job like so:

```ruby
class MyJob < ActiveJob::Base
  queue_as :my_jobs

  def perform(record)
    record.do_work
  end
end
```

Enqueue a job like so:

```ruby
MyJob.perform_later record  # Enqueue a job to be performed as soon as the queueing system is free.
```

```ruby
MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record)  # Enqueue a job to be performed tomorrow at noon.
```

```ruby
MyJob.set(wait: 1.week).perform_later(record) # Enqueue a job to be performed 1 week from now.
```

That's it!

## Supported types for arguments

ActiveJob supports the following types of arguments by default:

  - Standard types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
  - `Hash`. Keys should be of `String` or `Symbol` type
  - `ActiveSupport::HashWithIndifferentAccess`
  - `Array`


### GlobalID support

Active Job supports [GlobalID serialization](https://github.com/rails/globalid/) for parameters. This makes it possible
to pass live Active Record objects to your job instead of class/id pairs, which
you then have to manually deserialize. Before, jobs would look like this:

```ruby
class TrashableCleanupJob
  def perform(trashable_class, trashable_id, depth)
    trashable = trashable_class.constantize.find(trashable_id)
    trashable.cleanup(depth)
  end
end
```

Now you can simply do:

```ruby
class TrashableCleanupJob
  def perform(trashable, depth)
    trashable.cleanup(depth)
  end
end
```

This works with any class that mixes in GlobalID::Identification, which
by default has been mixed into Active Record classes.

### Serializers

You can extend list of supported types for arguments. You just need to define your own serializer.

```ruby
class MySpecialSerializer
  class << self
    # Check if this object should be serialized using this serializer
    def serialize?(argument)
      object.is_a? MySpecialValueObject
    end

    # Convert an object to a simpler representative using supported object types.
    # The recommended representative is a Hash with a specific key. Keys can be of basic types only
    def serialize(object)
      {
        key => ActiveJob::Serializers.serialize(object.value)
        'another_attribute' => ActiveJob::Serializers.serialize(object.another_attribute)
      }
    end

    # Check if this serialized value be deserialized using this serializer
    def deserialize?(argument)
      object.is_a?(Hash) && object.keys == [key, 'another_attribute']
    end

    # Convert serialized value into a proper object
    def deserialize(object)
      value = ActiveJob::Serializers.deserialize(object[key])
      another_attribute = ActiveJob::Serializers.deserialize(object['another_attribute'])
      MySpecialValueObject.new value, another_attribute
    end

    # Define this method if you are using a hash as a representative.
    # This key will be added to a list of restricted keys for hashes. Use basic types only
    def key
      "_aj_custom_dummy_value_object"
    end
  end
end
```

And now you just need to add this serializer to a list:

```ruby
ActiveJob::Base.add_serializers(MySpecialSerializer)
```

## Supported queueing systems

Active Job has built-in adapters for multiple queueing backends (Sidekiq,
Resque, Delayed Job and others). To get an up-to-date list of the adapters
see the API Documentation for [ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).

## Auxiliary gems

* [activejob-stats](https://github.com/seuros/activejob-stats)

## Download and installation

The latest version of Active Job can be installed with RubyGems:

```
  $ gem install activejob
```

Source code can be downloaded as part of the Rails project on GitHub:

* https://github.com/rails/rails/tree/master/activejob

## License

Active Job is released under the MIT license:

* https://opensource.org/licenses/MIT


## Support

API documentation is at:

* http://api.rubyonrails.org

Bug reports for the Ruby on Rails project can be filed here:

* https://github.com/rails/rails/issues

Feature requests should be discussed on the rails-core mailing list here:

* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core