active_job-performs 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +53 -35
- data/README.md +29 -19
- data/lib/active_job/performs/version.rb +1 -1
- data/lib/active_job/performs.rb +12 -14
- metadata +3 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 673105da38e705ba9aa778566a9d711a631aea27467a354a4fc4413e16b31ac3
|
|
4
|
+
data.tar.gz: 632442f9d0c25be20d47ecc4038b8d36e20d2b4797b5a1b622d3b5dead074cc4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f1569149e481246401f737e48a032d6d579bdfcf39751daafc5b4991eecd7017a3e646ed573101d8c65ae6acf36b371c75bf2ed793fa22fef77fd5ca93fa25d
|
|
7
|
+
data.tar.gz: f1df1f52d96bc4fff67af97b1f675669da1eec01423b48ecc36451e2c290111d205ef839da6abe36929ba3edf685998a473f73ee55f3b01286a2df083ebfa988
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,65 +1,83 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
active_job-performs (0.3.
|
|
4
|
+
active_job-performs (0.3.3)
|
|
5
5
|
activejob (>= 6.1)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
activejob (
|
|
11
|
-
activesupport (=
|
|
10
|
+
activejob (8.1.1)
|
|
11
|
+
activesupport (= 8.1.1)
|
|
12
12
|
globalid (>= 0.3.6)
|
|
13
|
-
activemodel (
|
|
14
|
-
activesupport (=
|
|
15
|
-
activerecord (
|
|
16
|
-
activemodel (=
|
|
17
|
-
activesupport (=
|
|
13
|
+
activemodel (8.1.1)
|
|
14
|
+
activesupport (= 8.1.1)
|
|
15
|
+
activerecord (8.1.1)
|
|
16
|
+
activemodel (= 8.1.1)
|
|
17
|
+
activesupport (= 8.1.1)
|
|
18
18
|
timeout (>= 0.4.0)
|
|
19
|
-
activesupport (
|
|
19
|
+
activesupport (8.1.1)
|
|
20
20
|
base64
|
|
21
21
|
bigdecimal
|
|
22
|
-
concurrent-ruby (~> 1.0, >= 1.
|
|
22
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
23
23
|
connection_pool (>= 2.2.5)
|
|
24
24
|
drb
|
|
25
25
|
i18n (>= 1.6, < 2)
|
|
26
|
+
json
|
|
27
|
+
logger (>= 1.4.2)
|
|
26
28
|
minitest (>= 5.1)
|
|
27
|
-
|
|
28
|
-
tzinfo (~> 2.0)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
securerandom (>= 0.3)
|
|
30
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
31
|
+
uri (>= 0.13.1)
|
|
32
|
+
base64 (0.3.0)
|
|
33
|
+
bigdecimal (3.3.1)
|
|
34
|
+
concurrent-ruby (1.3.5)
|
|
35
|
+
connection_pool (2.5.5)
|
|
36
|
+
date (3.5.0)
|
|
37
|
+
debug (1.11.0)
|
|
34
38
|
irb (~> 1.10)
|
|
35
39
|
reline (>= 0.3.8)
|
|
36
|
-
drb (2.2.
|
|
37
|
-
|
|
40
|
+
drb (2.2.3)
|
|
41
|
+
erb (6.0.0)
|
|
42
|
+
globalid (1.3.0)
|
|
38
43
|
activesupport (>= 6.1)
|
|
39
|
-
i18n (1.14.
|
|
44
|
+
i18n (1.14.7)
|
|
40
45
|
concurrent-ruby (~> 1.0)
|
|
41
|
-
io-console (0.
|
|
42
|
-
irb (1.
|
|
46
|
+
io-console (0.8.1)
|
|
47
|
+
irb (1.15.3)
|
|
48
|
+
pp (>= 0.6.0)
|
|
43
49
|
rdoc (>= 4.0.0)
|
|
44
50
|
reline (>= 0.4.2)
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
json (2.16.0)
|
|
52
|
+
logger (1.7.0)
|
|
53
|
+
minitest (5.26.2)
|
|
54
|
+
minitest-sprint (1.4.1)
|
|
47
55
|
path_expander (~> 1.1)
|
|
48
|
-
|
|
49
|
-
path_expander (1.1.
|
|
50
|
-
|
|
56
|
+
prism (~> 1.5)
|
|
57
|
+
path_expander (1.1.3)
|
|
58
|
+
pp (0.6.3)
|
|
59
|
+
prettyprint
|
|
60
|
+
prettyprint (0.2.0)
|
|
61
|
+
prism (1.6.0)
|
|
62
|
+
psych (5.2.6)
|
|
63
|
+
date
|
|
51
64
|
stringio
|
|
52
|
-
rake (13.
|
|
53
|
-
rdoc (6.
|
|
65
|
+
rake (13.3.1)
|
|
66
|
+
rdoc (6.16.1)
|
|
67
|
+
erb
|
|
54
68
|
psych (>= 4.0.0)
|
|
55
|
-
|
|
69
|
+
tsort
|
|
70
|
+
reline (0.6.3)
|
|
56
71
|
io-console (~> 0.5)
|
|
57
|
-
|
|
58
|
-
sqlite3 (
|
|
59
|
-
|
|
60
|
-
|
|
72
|
+
securerandom (0.4.1)
|
|
73
|
+
sqlite3 (2.8.0-arm64-darwin)
|
|
74
|
+
sqlite3 (2.8.0-x86_64-linux-gnu)
|
|
75
|
+
stringio (3.1.8)
|
|
76
|
+
timeout (0.4.4)
|
|
77
|
+
tsort (0.2.0)
|
|
61
78
|
tzinfo (2.0.6)
|
|
62
79
|
concurrent-ruby (~> 1.0)
|
|
80
|
+
uri (1.1.1)
|
|
63
81
|
|
|
64
82
|
PLATFORMS
|
|
65
83
|
arm64-darwin
|
|
@@ -73,7 +91,7 @@ DEPENDENCIES
|
|
|
73
91
|
minitest (~> 5.0)
|
|
74
92
|
minitest-sprint
|
|
75
93
|
rake (~> 13.0)
|
|
76
|
-
sqlite3
|
|
94
|
+
sqlite3
|
|
77
95
|
|
|
78
96
|
BUNDLED WITH
|
|
79
97
|
2.5.14
|
data/README.md
CHANGED
|
@@ -13,7 +13,7 @@ class Post < ApplicationRecord
|
|
|
13
13
|
end
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Here's what `performs` generates under the hood:
|
|
17
17
|
|
|
18
18
|
```ruby
|
|
19
19
|
class Post < ApplicationRecord
|
|
@@ -25,12 +25,12 @@ class Post < ApplicationRecord
|
|
|
25
25
|
def perform(post, *, **) = post.publish(*, **)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
# On Rails 7.1
|
|
28
|
+
# On Rails 7.1+, where `ActiveJob.perform_all_later` exists, we also generate
|
|
29
29
|
# a bulk method to enqueue many jobs at once. So you can do this:
|
|
30
30
|
#
|
|
31
31
|
# Post.unpublished.in_batches.each(&:publish_later_bulk)
|
|
32
|
-
def self.publish_later_bulk
|
|
33
|
-
ActiveJob.perform_all_later
|
|
32
|
+
def self.publish_later_bulk(set = all)
|
|
33
|
+
ActiveJob.perform_all_later set.map { PublishJob.new(_1) }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# We generate `publish_later` to wrap the job execution forwarding arguments and options.
|
|
@@ -55,7 +55,12 @@ end
|
|
|
55
55
|
> [!TIP]
|
|
56
56
|
> On that last point, `performs` does put more logic back within your Active Records, so if you need further encapsulation to prevent them growing too large, consider checking out [active_record-associated_object](https://github.com/kaspth/active_record-associated_object).
|
|
57
57
|
|
|
58
|
-
###
|
|
58
|
+
### Used in production & praise from people
|
|
59
|
+
|
|
60
|
+
The https://www.rubyevents.org team uses `ActiveJob::Performs` quite a bit:
|
|
61
|
+
|
|
62
|
+
- [See `performs` calls in RubyEvents](https://github.com/search?q=repo%3Arubyevents%2Frubyevents+performs+language%3ARuby&type=code&l=Ruby)
|
|
63
|
+
|
|
59
64
|
|
|
60
65
|
Here's what [@claudiob](https://github.com/claudiob) had to say after using `ActiveJob::Performs`:
|
|
61
66
|
|
|
@@ -85,7 +90,7 @@ class Post < ActiveRecord::Base
|
|
|
85
90
|
extend ActiveJob::Performs # We technically auto-extend ActiveRecord::Base, but other object hierarchies need this.
|
|
86
91
|
|
|
87
92
|
# `performs` builds a `Post::PublishJob` and routes configs over to it.
|
|
88
|
-
performs :publish, queue_as: :important, discard_on: SomeError do
|
|
93
|
+
performs :publish, queue_adapter: :sidekiq, queue_as: :important, discard_on: SomeError do
|
|
89
94
|
retry_on TimeoutError, wait: :polynomially_longer
|
|
90
95
|
end
|
|
91
96
|
|
|
@@ -104,6 +109,7 @@ class Post < ActiveRecord::Base
|
|
|
104
109
|
|
|
105
110
|
# Individual method jobs inherit from the `Post::Job` defined above.
|
|
106
111
|
class PublishJob < Job
|
|
112
|
+
self.queue_adapter = :sidekiq
|
|
107
113
|
queue_as :important
|
|
108
114
|
discard_on SomeError
|
|
109
115
|
retry_on TimeoutError, wait: :polynomially_longer
|
|
@@ -122,8 +128,8 @@ class Post < ActiveRecord::Base
|
|
|
122
128
|
# Or pass in a subset of posts as an argument:
|
|
123
129
|
#
|
|
124
130
|
# Post.publish_later_bulk Post.unpublished
|
|
125
|
-
def self.publish_later_bulk
|
|
126
|
-
ActiveJob.perform_all_later
|
|
131
|
+
def self.publish_later_bulk(set = all)
|
|
132
|
+
ActiveJob.perform_all_later set.map { PublishJob.new(_1) }
|
|
127
133
|
end
|
|
128
134
|
|
|
129
135
|
# We generate `publish_later` to wrap the job execution.
|
|
@@ -137,6 +143,9 @@ class Post < ActiveRecord::Base
|
|
|
137
143
|
end
|
|
138
144
|
```
|
|
139
145
|
|
|
146
|
+
> [!NOTE]
|
|
147
|
+
> We prefer & call `{name}=` setter methods, but fall back to getters. That's how we support `self.queue_adapter=`, but also `queue_as` which is not configured via `queue_as=`.
|
|
148
|
+
|
|
140
149
|
We generate the `Post::Job` class above to share configuration between method level jobs. E.g. if you had a `retract` method that was setup very similar, you could do:
|
|
141
150
|
|
|
142
151
|
```ruby
|
|
@@ -183,8 +192,7 @@ If there's an Active Record method that you'd like any model to be able to run f
|
|
|
183
192
|
class ApplicationRecord < ActiveRecord::Base
|
|
184
193
|
self.abstract_class = true
|
|
185
194
|
|
|
186
|
-
# We're passing specific queues for monitoring, but
|
|
187
|
-
performs :touch, queue_as: "active_record.touch"
|
|
195
|
+
# We're passing specific queues for monitoring, but they're optional.
|
|
188
196
|
performs :update, queue_as: "active_record.update"
|
|
189
197
|
performs :destroy, queue_as: "active_record.destroy"
|
|
190
198
|
end
|
|
@@ -193,19 +201,21 @@ end
|
|
|
193
201
|
Then a model could now run things like:
|
|
194
202
|
|
|
195
203
|
```ruby
|
|
196
|
-
record.
|
|
197
|
-
record.touch_later :reminded_at, time: 5.minutes.from_now # Pass supported arguments to `touch`
|
|
198
|
-
|
|
199
|
-
record.update_later reminded_at: 1.year.ago
|
|
200
|
-
|
|
201
|
-
# Particularly handy to use on a record with many `dependent: :destroy` associations.
|
|
202
|
-
# Plus if anything fails, the transaction will rollback and the job fails, so you can retry it later!
|
|
204
|
+
record.update_later reminded_at: 1.year.ago # Forward along arguments to the eventual `update` call.
|
|
203
205
|
record.destroy_later
|
|
204
206
|
```
|
|
205
207
|
|
|
206
|
-
|
|
208
|
+
> [!TIP]
|
|
209
|
+
> `destroy_later` could be particularly useful on a record with many `dependent: :destroy` associations.
|
|
210
|
+
> If anything fails, the transaction will rollback and the job fails, so you can retry it later!
|
|
211
|
+
|
|
212
|
+
> [!NOTE]
|
|
213
|
+
> Maybe you'd rather architect your system such that these methods don't have so many side-effects, but having the option can be handy.
|
|
214
|
+
|
|
215
|
+
> [!WARNING]
|
|
216
|
+
> Don't use this pattern with `touch` because Rails has an internal [touch_later](https://github.com/rails/rails/blob/690ec8898318b8f50714e86676353ebe1551261e/activerecord/lib/active_record/touch_later.rb#L11) private API method used in `belongs_to <some_association>, touch: true` assocations. If your model is one day used in such an assocation and you were using this pattern your app would break.
|
|
207
217
|
|
|
208
|
-
|
|
218
|
+
I haven't tested all the Active Record methods, so please file an issue if you encounter any.
|
|
209
219
|
|
|
210
220
|
#### Method suffixes
|
|
211
221
|
|
data/lib/active_job/performs.rb
CHANGED
|
@@ -5,18 +5,14 @@ require_relative "performs/version"
|
|
|
5
5
|
module ActiveJob; end
|
|
6
6
|
module ActiveJob::Performs
|
|
7
7
|
module Waiting
|
|
8
|
-
|
|
9
|
-
value.respond_to?(:call) ? value : proc { value }
|
|
10
|
-
end unless Kernel.respond_to?(:Proc) # Optimistically assume Ruby gets this and it'll work fine.
|
|
8
|
+
attr_reader :wait, :wait_until
|
|
11
9
|
|
|
12
|
-
def wait(value
|
|
13
|
-
@wait =
|
|
14
|
-
@wait
|
|
10
|
+
def wait=(value)
|
|
11
|
+
@wait = value.respond_to?(:call) ? value : proc { value }
|
|
15
12
|
end
|
|
16
13
|
|
|
17
|
-
def wait_until(value
|
|
18
|
-
@wait_until =
|
|
19
|
-
@wait_until
|
|
14
|
+
def wait_until=(value)
|
|
15
|
+
@wait_until = value.respond_to?(:call) ? value : proc { value }
|
|
20
16
|
end
|
|
21
17
|
|
|
22
18
|
def scoped_by_wait(record)
|
|
@@ -59,8 +55,6 @@ module ActiveJob::Performs
|
|
|
59
55
|
#{job}.scoped_by_wait(self).perform_later(self, *arguments, **options)
|
|
60
56
|
end
|
|
61
57
|
RUBY
|
|
62
|
-
|
|
63
|
-
[method, :"#{method}_later#{suffix}"] # Ensure `private performs :some_method` privates both names.
|
|
64
58
|
end
|
|
65
59
|
end
|
|
66
60
|
|
|
@@ -69,9 +63,13 @@ module ActiveJob::Performs
|
|
|
69
63
|
name.safe_constantize || const_set(name, Class.new(yield))
|
|
70
64
|
end
|
|
71
65
|
|
|
72
|
-
def apply_performs_to(
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
def apply_performs_to(job, **configs, &block)
|
|
67
|
+
job.class_exec(&block) if block_given?
|
|
68
|
+
|
|
69
|
+
configs.each do |name, value|
|
|
70
|
+
name = "#{name}=".then.find { job.respond_to? _1 } || name
|
|
71
|
+
job.public_send name, value
|
|
72
|
+
end
|
|
75
73
|
end
|
|
76
74
|
|
|
77
75
|
def performs_later_methods
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_job-performs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kasper Timm Hansen
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activejob
|
|
@@ -24,7 +23,6 @@ dependencies:
|
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: '6.1'
|
|
27
|
-
description:
|
|
28
26
|
email:
|
|
29
27
|
- hey@kaspth.com
|
|
30
28
|
executables: []
|
|
@@ -47,7 +45,6 @@ metadata:
|
|
|
47
45
|
homepage_uri: https://github.com/kaspth/active_job-performs
|
|
48
46
|
source_code_uri: https://github.com/kaspth/active_job-performs
|
|
49
47
|
changelog_uri: https://github.com/kaspth/active_job-performs/blob/main/CHANGELOG.md
|
|
50
|
-
post_install_message:
|
|
51
48
|
rdoc_options: []
|
|
52
49
|
require_paths:
|
|
53
50
|
- lib
|
|
@@ -62,8 +59,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
62
59
|
- !ruby/object:Gem::Version
|
|
63
60
|
version: '0'
|
|
64
61
|
requirements: []
|
|
65
|
-
rubygems_version: 3.
|
|
66
|
-
signing_key:
|
|
62
|
+
rubygems_version: 3.7.2
|
|
67
63
|
specification_version: 4
|
|
68
64
|
summary: ActiveJob::Performs adds the `performs` macro to set up jobs by convention.
|
|
69
65
|
test_files: []
|