active_job-performs 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: afad0c3e092f329deb71fea10b4f2105d1a2fbff2d581eb46304411c8cf5c592
4
- data.tar.gz: ec2db477f5e639b8dd8f4e1958f2f2813e9d32a85b6526693878a10927da6f0a
3
+ metadata.gz: a4395366ab43af9510f569bcc141c9404a15fd2d6da529029eedc970c7a8f886
4
+ data.tar.gz: 9e239bf9a60e4e2785ae4b104f2cfd01e9b832729202f78ad9443c82046a7be6
5
5
  SHA512:
6
- metadata.gz: 0213fcbdd14ecc60adbbff93d2f515b1ec1dee6f9511d9b69037ac2e85610cbaa9b3458a0b5256cba2f18f2d5e3f814dddf04e2993e89e3b0e44151b0cbc5819
7
- data.tar.gz: 6bf98a858966a833b872643a3fc5b33f23d27d1499eaf8b917f5c470bb43b49cd2e8c68c8f0cad251714a84c7da2a531d4809e72b8db364818a8d76bbe827107
6
+ metadata.gz: 678c75e3a24b9faa407b01a063c15fadefc23747489b9e55db52641298385f2632b91268ae20ef9bf4964562e36ed5b6df99d46b1384605fb0ee694e29c0ae3d
7
+ data.tar.gz: 22231da5fc1856e480d00329e5a0cbf2482840d48eb2b2ea716751cbcc0d413d65169252aa8f3cc021b6f474e80f2a98912ce63bc1916ad2d2c1b29a3c7d273a
data/Gemfile CHANGED
@@ -9,3 +9,11 @@ gem "rake", "~> 13.0"
9
9
 
10
10
  gem "minitest", "~> 5.0"
11
11
  gem "minitest-sprint"
12
+
13
+ gem "debug"
14
+
15
+ # Fetch latest Active Job to test `ActiveJob.perform_all_later`
16
+ gem "activejob", ">= 7.1"
17
+ gem "activerecord", ">= 7.1"
18
+
19
+ gem "sqlite3", "~> 1.4"
data/Gemfile.lock CHANGED
@@ -1,42 +1,79 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_job-performs (0.2.0)
4
+ active_job-performs (0.3.1)
5
5
  activejob (>= 6.1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activejob (7.0.4)
11
- activesupport (= 7.0.4)
10
+ activejob (7.1.3.3)
11
+ activesupport (= 7.1.3.3)
12
12
  globalid (>= 0.3.6)
13
- activesupport (7.0.4)
13
+ activemodel (7.1.3.3)
14
+ activesupport (= 7.1.3.3)
15
+ activerecord (7.1.3.3)
16
+ activemodel (= 7.1.3.3)
17
+ activesupport (= 7.1.3.3)
18
+ timeout (>= 0.4.0)
19
+ activesupport (7.1.3.3)
20
+ base64
21
+ bigdecimal
14
22
  concurrent-ruby (~> 1.0, >= 1.0.2)
23
+ connection_pool (>= 2.2.5)
24
+ drb
15
25
  i18n (>= 1.6, < 2)
16
26
  minitest (>= 5.1)
27
+ mutex_m
17
28
  tzinfo (~> 2.0)
18
- concurrent-ruby (1.1.10)
19
- globalid (1.0.0)
20
- activesupport (>= 5.0)
21
- i18n (1.12.0)
29
+ base64 (0.2.0)
30
+ bigdecimal (3.1.8)
31
+ concurrent-ruby (1.2.3)
32
+ connection_pool (2.4.1)
33
+ debug (1.9.2)
34
+ irb (~> 1.10)
35
+ reline (>= 0.3.8)
36
+ drb (2.2.1)
37
+ globalid (1.2.1)
38
+ activesupport (>= 6.1)
39
+ i18n (1.14.5)
22
40
  concurrent-ruby (~> 1.0)
23
- minitest (5.16.3)
41
+ io-console (0.7.2)
42
+ irb (1.13.1)
43
+ rdoc (>= 4.0.0)
44
+ reline (>= 0.4.2)
45
+ minitest (5.23.1)
24
46
  minitest-sprint (1.2.2)
25
47
  path_expander (~> 1.1)
48
+ mutex_m (0.2.0)
26
49
  path_expander (1.1.1)
27
- rake (13.0.6)
28
- tzinfo (2.0.5)
50
+ psych (5.1.2)
51
+ stringio
52
+ rake (13.2.1)
53
+ rdoc (6.7.0)
54
+ psych (>= 4.0.0)
55
+ reline (0.5.7)
56
+ io-console (~> 0.5)
57
+ sqlite3 (1.7.3-arm64-darwin)
58
+ sqlite3 (1.7.3-x86_64-linux)
59
+ stringio (3.1.0)
60
+ timeout (0.4.1)
61
+ tzinfo (2.0.6)
29
62
  concurrent-ruby (~> 1.0)
30
63
 
31
64
  PLATFORMS
32
- arm64-darwin-20
65
+ arm64-darwin
33
66
  x86_64-linux
34
67
 
35
68
  DEPENDENCIES
36
69
  active_job-performs!
70
+ activejob (>= 7.1)
71
+ activerecord (>= 7.1)
72
+ debug
37
73
  minitest (~> 5.0)
38
74
  minitest-sprint
39
75
  rake (~> 13.0)
76
+ sqlite3 (~> 1.4)
40
77
 
41
78
  BUNDLED WITH
42
- 2.3.21
79
+ 2.5.4
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `ActiveJob::Performs` adds the `performs` macro to set up jobs by convention.
4
4
 
5
- ## Usage with `include GlobalID::Identification` objects
5
+ ## Usage with `ActiveRecord::Base` & other `GlobalID::Identification` objects
6
6
 
7
7
  `ActiveJob::Performs` works with any object that has `include GlobalID::Identification` and responds to that interface.
8
8
 
@@ -14,7 +14,7 @@ class Post < ActiveRecord::Base
14
14
 
15
15
  # `performs` builds a `Post::PublishJob` and routes configs over to it.
16
16
  performs :publish, queue_as: :important, discard_on: SomeError do
17
- retry_on TimeoutError, wait: :exponentially_longer
17
+ retry_on TimeoutError, wait: :polynomially_longer
18
18
  end
19
19
 
20
20
  def publish
@@ -34,7 +34,7 @@ class Post < ActiveRecord::Base
34
34
  class PublishJob < Job
35
35
  queue_as :important
36
36
  discard_on SomeError
37
- retry_on TimeoutError, wait: :exponentially_longer
37
+ retry_on TimeoutError, wait: :polynomially_longer
38
38
 
39
39
  # We generate `perform` passing in the `post` and calling `publish` on it.
40
40
  def perform(post, *arguments, **options)
@@ -42,6 +42,14 @@ class Post < ActiveRecord::Base
42
42
  end
43
43
  end
44
44
 
45
+ # On Rails 7.1, where `ActiveJob.perform_all_later` exists, we also generate
46
+ # a bulk method to enqueue many jobs at once. So you can do this:
47
+ #
48
+ # Post.unpublished.in_batches.each(&:publish_later_bulk)
49
+ def self.publish_later_bulk
50
+ ActiveJob.perform_all_later all.map { PublishJob.new(_1) }
51
+ end
52
+
45
53
  # We generate `publish_later` to wrap the job execution.
46
54
  def publish_later(*arguments, **options)
47
55
  PublishJob.perform_later(self, *arguments, **options)
@@ -91,6 +99,38 @@ class Post < ActiveRecord::Base
91
99
  end
92
100
  ```
93
101
 
102
+ #### Establishing patterns across your app
103
+
104
+ If there's an Active Record method that you'd like any model to be able to run from a background job, you can set them up in your `ApplicationRecord`:
105
+
106
+ ```ruby
107
+ class ApplicationRecord < ActiveRecord::Base
108
+ self.abstract_class = true
109
+
110
+ # We're passing specific queues for monitoring, but you may not need or want them.
111
+ performs :touch, queue_as: "active_record.touch"
112
+ performs :update, queue_as: "active_record.update"
113
+ performs :destroy, queue_as: "active_record.destroy"
114
+ end
115
+ ```
116
+
117
+ Then a model could now run things like:
118
+
119
+ ```ruby
120
+ record.touch_later
121
+ record.touch_later :reminded_at, time: 5.minutes.from_now # Pass supported arguments to `touch`
122
+
123
+ record.update_later reminded_at: 1.year.ago
124
+
125
+ # Particularly handy to use on a record with many `dependent: :destroy` associations.
126
+ # Plus if anything fails, the transaction will rollback and the job fails, so you can retry it later!
127
+ record.destroy_later
128
+ ```
129
+
130
+ You may not want this for `touch` and `update`, and maybe you'd rather architect your system in such a way that they don't have so many side-effects, but having the option can be handy!
131
+
132
+ Also, I haven't tested all the Active Record methods, so please file an issue if you encounter any.
133
+
94
134
  #### Method suffixes
95
135
 
96
136
  `ActiveJob::Performs` supports Ruby's stylistic method suffixes, i.e. ? and ! respectively.
@@ -129,7 +169,20 @@ Additionally, in case the job is meant to be internal to the object, `performs :
129
169
 
130
170
  E.g. `private performs :some_method` will generate a private `some_method_later` method.
131
171
 
132
- ### Usage with ActiveRecord::AssociatedObject
172
+ #### Overriding the generated instance `_later` method
173
+
174
+ The instance level `_later` methods, like `publish_later` above, are generated into an included module. So in case you have a condition where you'd like to prevent the enqueue, you can override the method and call `super`:
175
+
176
+ ```ruby
177
+ class Post < ApplicationRecord
178
+ performs def publish
179
+ # …
180
+ end
181
+ def publish_later = some_condition? && super
182
+ end
183
+ ```
184
+
185
+ ### Usage with `ActiveRecord::AssociatedObject`
133
186
 
134
187
  The [`ActiveRecord::AssociatedObject`](https://github.com/kaspth/active_record-associated_object) gem also implements `GlobalID::Identification`, so you can do this too:
135
188
 
@@ -177,6 +230,12 @@ class Post < ActiveRecord::Base
177
230
  end
178
231
  ```
179
232
 
233
+ ### Praise from people
234
+
235
+ Here's what [@nshki](https://github.com/nshki) found when they tried `ActiveJob::Performs`:
236
+
237
+ > Spent some time playing with [@kaspth](https://github.com/kaspth)'s [`ActiveRecord::AssociatedObject`](https://github.com/kaspth/active_record-associated_object) and `ActiveJob::Performs` and wow! The conventions these gems put in place help simplify a codebase drastically. I particularly love `ActiveJob::Performs`—it helped me refactor out all `ApplicationJob` classes I had and keep important context in the right domain model.
238
+
180
239
  ## Installation
181
240
 
182
241
  Install the gem and add to the application's Gemfile by executing:
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveJob
4
4
  module Performs
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.1"
6
6
  end
7
7
  end
@@ -46,11 +46,21 @@ module ActiveJob::Performs
46
46
  end
47
47
  RUBY
48
48
 
49
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
49
+ if ActiveJob.respond_to?(:perform_all_later) && respond_to?(:all)
50
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
51
+ def self.#{method}_later_bulk#{suffix}
52
+ ActiveJob.perform_all_later all.map { #{job}.scoped_by_wait(_1).new(_1) }
53
+ end
54
+ RUBY
55
+ end
56
+
57
+ performs_later_methods.class_eval <<~RUBY, __FILE__, __LINE__ + 1
50
58
  def #{method}_later#{suffix}(*arguments, **options)
51
59
  #{job}.scoped_by_wait(self).perform_later(self, *arguments, **options)
52
60
  end
53
61
  RUBY
62
+
63
+ [method, :"#{method}_later#{suffix}"] # Ensure `private performs :some_method` privates both names.
54
64
  end
55
65
  end
56
66
 
@@ -63,6 +73,10 @@ module ActiveJob::Performs
63
73
  configs.each { job_class.public_send(_1, _2) }
64
74
  job_class.class_exec(&block) if block_given?
65
75
  end
76
+
77
+ def performs_later_methods
78
+ @performs_later_methods ||= Module.new.tap { include _1 }
79
+ end
66
80
  end
67
81
 
68
82
  ActiveSupport.on_load(:active_record) { extend ActiveJob::Performs }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_job-performs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kasper Timm Hansen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-12 00:00:00.000000000 Z
11
+ date: 2024-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -62,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  requirements: []
65
- rubygems_version: 3.4.1
65
+ rubygems_version: 3.5.10
66
66
  signing_key:
67
67
  specification_version: 4
68
68
  summary: ActiveJob::Performs adds the `performs` macro to set up jobs by convention.