active_job-performs 0.2.0 → 0.3.1

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 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.