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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 566acd14649609a2e16b658a93fe276f80609866c61fb37c11e720b581bc0f76
4
- data.tar.gz: 5174b18e562c53966639bb16e3d729885d99f1ebe01163175a1513dded11cbff
3
+ metadata.gz: 673105da38e705ba9aa778566a9d711a631aea27467a354a4fc4413e16b31ac3
4
+ data.tar.gz: 632442f9d0c25be20d47ecc4038b8d36e20d2b4797b5a1b622d3b5dead074cc4
5
5
  SHA512:
6
- metadata.gz: f2fd767c6bd1c66d26a046e84dea4cd2ea0bfdb0ec50452699151e90fba9856b14875ab1a98371cf2727423a31871db4af432a965784a9cf61d92b58917ce0d2
7
- data.tar.gz: cd9628dce5378c14ecae35da1fc83ae4487ea0ece02a5e4a78226572778ca7d370c5975e99ff880fa9bf030f026c244d1d3cf2abac838fb7d1bec373f7327cbf
6
+ metadata.gz: 7f1569149e481246401f737e48a032d6d579bdfcf39751daafc5b4991eecd7017a3e646ed573101d8c65ae6acf36b371c75bf2ed793fa22fef77fd5ca93fa25d
7
+ data.tar.gz: f1df1f52d96bc4fff67af97b1f675669da1eec01423b48ecc36451e2c290111d205ef839da6abe36929ba3edf685998a473f73ee55f3b01286a2df083ebfa988
data/Gemfile CHANGED
@@ -16,4 +16,4 @@ gem "debug"
16
16
  gem "activejob", ">= 7.1"
17
17
  gem "activerecord", ">= 7.1"
18
18
 
19
- gem "sqlite3", "~> 1.4"
19
+ gem "sqlite3"
data/Gemfile.lock CHANGED
@@ -1,65 +1,83 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_job-performs (0.3.2)
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 (7.1.3.4)
11
- activesupport (= 7.1.3.4)
10
+ activejob (8.1.1)
11
+ activesupport (= 8.1.1)
12
12
  globalid (>= 0.3.6)
13
- activemodel (7.1.3.4)
14
- activesupport (= 7.1.3.4)
15
- activerecord (7.1.3.4)
16
- activemodel (= 7.1.3.4)
17
- activesupport (= 7.1.3.4)
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 (7.1.3.4)
19
+ activesupport (8.1.1)
20
20
  base64
21
21
  bigdecimal
22
- concurrent-ruby (~> 1.0, >= 1.0.2)
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
- mutex_m
28
- tzinfo (~> 2.0)
29
- base64 (0.2.0)
30
- bigdecimal (3.1.8)
31
- concurrent-ruby (1.3.3)
32
- connection_pool (2.4.1)
33
- debug (1.9.2)
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.1)
37
- globalid (1.2.1)
40
+ drb (2.2.3)
41
+ erb (6.0.0)
42
+ globalid (1.3.0)
38
43
  activesupport (>= 6.1)
39
- i18n (1.14.5)
44
+ i18n (1.14.7)
40
45
  concurrent-ruby (~> 1.0)
41
- io-console (0.7.2)
42
- irb (1.13.2)
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
- minitest (5.24.0)
46
- minitest-sprint (1.2.2)
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
- mutex_m (0.2.0)
49
- path_expander (1.1.1)
50
- psych (5.1.2)
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.2.1)
53
- rdoc (6.7.0)
65
+ rake (13.3.1)
66
+ rdoc (6.16.1)
67
+ erb
54
68
  psych (>= 4.0.0)
55
- reline (0.5.9)
69
+ tsort
70
+ reline (0.6.3)
56
71
  io-console (~> 0.5)
57
- sqlite3 (1.7.3-arm64-darwin)
58
- sqlite3 (1.7.3-x86_64-linux)
59
- stringio (3.1.1)
60
- timeout (0.4.1)
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 (~> 1.4)
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
- Then we build a job for the instance method and define a `post.publish_later` instance method, and more:
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, where `ActiveJob.perform_all_later` exists, we also generate
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 all.map { PublishJob.new(_1) }
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
- ### Praise from people
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 all.map { PublishJob.new(_1) }
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 you may not need or want them.
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.touch_later
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
- 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!
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
- Also, I haven't tested all the Active Record methods, so please file an issue if you encounter any.
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
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveJob
4
4
  module Performs
5
- VERSION = "0.3.2"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
@@ -5,18 +5,14 @@ require_relative "performs/version"
5
5
  module ActiveJob; end
6
6
  module ActiveJob::Performs
7
7
  module Waiting
8
- def Proc(value)
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 = nil)
13
- @wait = Proc(value) if value
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 = nil)
18
- @wait_until = Proc(value) if value
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(job_class, **configs, &block)
73
- configs.each { job_class.public_send(_1, _2) }
74
- job_class.class_exec(&block) if block_given?
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.3.2
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: 2024-12-16 00:00:00.000000000 Z
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.5.18
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: []