postburner 0.3.1 → 0.5.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: 9b66577a3987f1041207f3ccd0b64f50d259dfdd32f4d2922cb309bcb381e038
4
- data.tar.gz: c0742f5c7539738ccdc2346bb475cddb5299737317d8d08b114e35ad9ee67888
3
+ metadata.gz: ffbffc2cebbe2e83bfff21178b71d0b205756cd6ef05c6dc30c8029d073c70d7
4
+ data.tar.gz: 68136a8de901340817dcd60e0fbd3b6794eb6dea2f8da386af138576dbba6334
5
5
  SHA512:
6
- metadata.gz: bea9ab0743648db32d1a7b37887d9baa942b9bf415ed9265d6dfef0f7d924fedaa70443518c3c0a59990311fa9c69f41dc1643aaa75726c9b75ebd47f4068c7a
7
- data.tar.gz: 335324c1a10818d353f90ee719ddb9d57be98cb04fd648ac222993294a2cb1f2824f57e3c932a8d5d720614fe51323082637aa2bed2d535411e8a8b8be543713
6
+ metadata.gz: 319ebb136625b266efe9189c8f6114ee7153ad18503b6d38343609a8bcb62dc3ea814b4b22e60f685f90f68957a2c9647ff3c958e26983796fc2c40bb8cb981c
7
+ data.tar.gz: 0fb16c1e08994dc7676b1546dc9d492c51243a9bcf8ffa9a2367b0a4274ecd806c322f00b6304a637fbfa20ddb2bc0872bd5ccdb357bba1d518f60f589edbf46
data/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.5.0 - 2021-10-27
4
+
5
+ ### Added
6
+ - add mailer, action, params accessors to Mailer for easy access in subclassed jobs.
7
+ - add logging to Mailer perform.
8
+ - add save to #queue! job if unsaved
9
+ - add block with logging if queued_at isn't set or isn't prior to run time.
10
+
11
+ ## v0.4.0 - 2021-10-12
12
+
13
+ ### Added
14
+ - Change Job logging to persisted in perform.
15
+ - Update mailer job to use #with and support serializations.
16
+
17
+ ## v0.3.3 - 2021-06-15
18
+
19
+ ### Fixed
20
+ - re-raise exception after logging during perform.
21
+ - log but swallow post perform data update exceptions.
22
+ - only allow remove! if job still present.
23
+
24
+ ### Added
25
+ - Job#log! and Job#log_exception! that save the data immediately.
26
+
27
+ ## v0.3.2 - 2021-05-07
28
+
29
+ ### Fixed
30
+ - add processed_at guard w/ logs.
31
+
3
32
  ## v0.3.1 - 2021-05-07
4
33
 
5
34
  ### Fixed
data/README.md CHANGED
@@ -1,29 +1,15 @@
1
1
  # Postburner
2
- An ActiveRecord layer on top of Backburner for inspecting and auditing the
3
- queue, especially for delayed jobs. It isn't meant to be fast, but safe.
2
+ An ActiveRecord layer on top of [Backburner](https://github.com/nesquena/backburner) for inspecting and auditing the
3
+ queue, especially for delayed jobs. It isn't meant to be outperform other queues, but be safe (and inspectable).
4
4
 
5
- It is meant to be complementary to Backburner. Use Backburner as the default
5
+ It is meant to be complementary to [Backburner](https://github.com/nesquena/backburner). Use Backburner as the default
6
6
  ActiveJob processor for mailers, active storage, and the like. Use a
7
- `Postburner::Job` for things that you want to track.
7
+ `Postburner::Job` for things that you want to track. See [Comparison to Backburner](#comparison-to-backburner) for more.
8
8
 
9
- Comes with a mountable interface that can be password protected with whatever
10
- authentication you use in your project.
11
-
12
- Also meant to be a replacement/upgrade for [Que](https://github.com/que-rb/que).
13
- If you need something faster, but backed with ACID compliance, check out Que.
14
- There are some additional features in Postburner such as retained jobs
15
- after processing, stats, per job logging, etc.
16
-
17
- Compared to plain [Backburner](https://github.com/nesquena/backburner),
18
- Postburner adds:
19
- - Database Jobs for inspection, linking, auditing, removal (and deletion)
20
- - Direct access to associated [Beanstalk](https://beanstalkd.github.io/) (via [beaneater](https://github.com/beanstalkd/beaneater))
21
- - Job Statistics (lag, attempts, logs, tracked errors)
22
- - Convenience methods to clear tubes, stats, and connections for Beanstalk.
23
-
24
- Otherwise, Postburner tries to be a super simple layer on `Backburner::Queue`
25
- and `ActiveRecord`. Every tool with either of those are avilabel in
26
- `Postburner::Job`s.
9
+ Postburner meant to be a replacement/upgrade for [Que](https://github.com/que-rb/que).
10
+ If you need something faster, check out Que - we love it! Postburner is built for a slightly different purpose: to be
11
+ simple, safe, and inspectable. All of which Que has (or can be added), but are included by default with some architecture
12
+ differences. See [Comparison to Que](#comparison-to-que) for more.
27
13
 
28
14
  ## Usage
29
15
 
@@ -33,51 +19,240 @@ class RunDonation < Postburner::Job
33
19
  queue_priority 0 # 0 is highest priority
34
20
  queue_max_job_retries 0 # don't retry
35
21
 
36
- def process(args)
22
+ def perform(args)
37
23
  # do long tasks here
38
24
  # also have access to self.args
39
25
  end
40
26
  end
41
27
 
42
- RunDonation.create!(args: {donation_id: 123}).queue!
28
+ # RunDonation#create! is the `ActiveRecord` method, so it returns a model,
29
+ # you can manipulate, add columns to the table to, reference with foreign
30
+ # keys, etc.
31
+ job = RunDonation.create!(args: {donation_id: 123})
32
+ # NOTE Make sure use use an after_commit or after_save_commit, etc to avoid
33
+ # any race conditions of Postburner trying to process before a required
34
+ # database mutation is commited.
35
+ job.queue!
43
36
  => {:status=>"INSERTED", :id=>"1139"}
37
+
38
+ # queue for later with `:at`
44
39
  RunDonation.create!(args: {donation_id: 123}).queue! at: Time.zone.now + 2.days
45
40
  => {:status=>"INSERTED", :id=>"1140"}
46
41
 
47
- # `delay` takes priority over `at`
42
+ # queue for later with `:delay`
43
+ #
44
+ # `:delay` takes priority over `:at`takes priority over `:at` because the
45
+ # beanstalkd protocol uses uses `delay`
48
46
  RunDonation.create!(args: {donation_id: 123}).queue! delay: 1.hour
49
47
  => {:status=>"INSERTED", :id=>"1141"}
50
48
  ```
51
49
 
50
+ ### [Beaneater](https://github.com/beanstalkd/beaneater) and [beanstalkd](https://raw.githubusercontent.com/beanstalkd/beanstalkd/master/doc/protocol.txt) attributes and methods
51
+ ```ruby
52
+ # get the beanstalkd job id
53
+ job.bkid
54
+ => 1104
55
+
56
+ # get the beaneater job, call any beaneater methods on this object
57
+ job.beanstalk_job
58
+
59
+ # get the beanstald stats
60
+ job.beanstalk_job.stats
61
+
62
+ # kick the beanstalk job
63
+ job.kick!
64
+
65
+ # delete beankstalkd job, retain the job model
66
+ job.delete!
67
+
68
+ # delete beankstalkd job, retain the job model, but set `removed_at` on model.
69
+ job.remove!
70
+
71
+ # or simply remove the model, which will clean up the beanstalkd job in a before_destroy hook
72
+ job.destroy # OR job.destroy!
73
+
74
+ # get a cached Backburner connection and inspect it (or even use it directly)
75
+ c = Postburner.connection
76
+ c.beanstalk.tubes.to_a
77
+ c.beanstalk.tubes.to_a.map{|t| c.tubes[t.name].peek(:buried)}
78
+ c.beanstalk.tubes['ss.development.caching'].stats
79
+ c.beanstalk.tubes['ss.development.caching'].peek(:buried).kick
80
+ c.beanstalk.tubes['ss.development.caching'].kick(3)
81
+ c.close
82
+
83
+ # automatically close
84
+ Postburner.connected do |connection|
85
+ # do stuff with connection
86
+ end
87
+ ```
88
+
89
+ Read about the [beanstalkd protocol](https://raw.githubusercontent.com/beanstalkd/beanstalkd/master/doc/protocol.txt).
90
+
91
+ ### Basic model fields
92
+ ```ruby
93
+ # ActiveRecord primary key
94
+ job.id
95
+
96
+ # int id of the beankstalkd job
97
+ job.bkid
98
+
99
+ # string uuid
100
+ job.sid
101
+
102
+ # ActiveRecord STI job subtype
103
+ job.type
104
+
105
+ # jsonb arguments for use in job
106
+ job.args
107
+
108
+ # time job should run - not intended to be changed
109
+ # TODO run_at should be readonly after create
110
+ job.run_at
111
+ ```
112
+
113
+ ### Job statistics
114
+ ```ruby
115
+ # when job was inserted into beankstalkd
116
+ job.queued_at
117
+
118
+ # last time attempted
119
+ job.attempting_at
120
+
121
+ # last time processing started
122
+ job.processing_at
123
+
124
+ # when completed
125
+ job.processed_at
126
+
127
+ # when removed, may be nil
128
+ job.removed_at
129
+
130
+ # lag in ms from run_at/queued_at to attempting_at
131
+ job.lag
132
+
133
+ # duration of processing in ms
134
+ job.duration
135
+
136
+ # number of attempts
137
+ job.attempt_count
138
+
139
+ # number of errors (length of errata)
140
+ job.error_count
141
+
142
+ # number of log entries (length of logs)
143
+ job.log_count
144
+
145
+ # array of attempting_at times
146
+ job.attempts
147
+
148
+ # array of errors
149
+ job.errata
150
+
151
+ # array of log messages
152
+ job.logs
153
+ ```
154
+
155
+ ### Job logging and exceptions
156
+
157
+ Optionally, you can:
158
+ 1. Add log messages to the job during processing to `logs`
159
+ 1. Add log your own exceptions to `errata`
160
+
161
+ ```ruby
162
+ class RunDonation < Postburner::Job
163
+ queue 'critical'
164
+ queue_priority 0 # 0 is highest priority
165
+ queue_max_job_retries 0 # don't retry
166
+
167
+ def perform(args)
168
+ # log at task, defaults to `:info`, but `:debug`, `:warning`, `:error`
169
+ log "Log bad condition...", level: :error
170
+
171
+ begin
172
+ # danger
173
+ rescue Exception => e
174
+ log_exception e
175
+ end
176
+ end
177
+ end
178
+ ```
179
+
180
+ ### Optionally, mount the engine
181
+
182
+ ```ruby
183
+ mount Postburner::Engine => "/postburner"
184
+
185
+ # mount only for development inspection
186
+ mount Postburner::Engine => "/postburner" if Rails.env.development?
187
+ ```
188
+
189
+ [Open the controller](https://guides.rubyonrails.org/engines.html#overriding-models-and-controllers)
190
+ to add your own authentication or changes - or just create your own routes, controllers, and views.
191
+
192
+ [Override the views](https://guides.rubyonrails.org/engines.html#overriding-views) to make them
193
+ prettier - or follow the suggestion above and use your own.
194
+
52
195
  ## Installation
53
196
 
197
+ First [install beanstalkd](https://beanstalkd.github.io/download.html). On Debian-based systems, that goes like this:
198
+ ```bash
199
+ sudo apt-get install beanstalkd
200
+ ```
201
+
202
+ Then add to your Gemfile.
54
203
  ```ruby
55
- # in Gemfile
56
204
  gem 'postburner'
57
205
  ```
58
206
 
207
+ Install...
59
208
  ```bash
60
209
  $ bundle
210
+ ```
61
211
 
212
+ After bundling, install the migration.
213
+ ```
62
214
  # install migration, possible to edit and add attributes or indexes as needed.
63
215
  $ bundle exec rails g postburner:install
64
216
  ```
65
217
 
66
- Add a `config/initializers/backburner.rb` with option found [here](https://github.com/nesquena/backburner#configuration).
218
+ Inspect `XXX_create_postburner_jobs.rb`. (The template is [here](-/blob/master/lib/generators/postburner/install/templates/migrations/create_postburner_jobs.rb.erb)).The required attributes are in there, but add more if you would like to use them,
219
+ or do it in a separate migration. By default, several indexes are added
67
220
 
68
- Set `Backburner` for `ActiveJob`
221
+ Because `Postburner` is built on `Backburner`, add a `config/initializers/backburner.rb` with option found [here](https://github.com/nesquena/backburner#configuration).
222
+ ```ruby
223
+ Backburner.configure do |config|
224
+ config.beanstalk_url = "beanstalk://127.0.0.1"
225
+ config.tube_namespace = "some.app.production"
226
+ config.namespace_separator = "."
227
+ config.on_error = lambda { |e| puts e }
228
+ config.max_job_retries = 3 # default 0 retries
229
+ config.retry_delay = 2 # default 5 seconds
230
+ config.retry_delay_proc = lambda { |min_retry_delay, num_retries| min_retry_delay + (num_retries ** 3) }
231
+ config.default_priority = 65536
232
+ config.respond_timeout = 120
233
+ config.default_worker = Backburner::Workers::Simple
234
+ config.logger = Logger.new(STDOUT)
235
+ config.primary_queue = "backburner-jobs"
236
+ config.priority_labels = { :custom => 50, :useless => 1000 }
237
+ config.reserve_timeout = nil
238
+ config.job_serializer_proc = lambda { |body| JSON.dump(body) }
239
+ config.job_parser_proc = lambda { |body| JSON.parse(body) }
240
+ end
241
+ ```
242
+
243
+ Finally, set `Backburner` for `ActiveJob`
69
244
  ```
70
245
  # config/application.rb
71
246
  config.active_job.queue_adapter = :backburner
72
247
  ```
73
248
 
74
249
  Postburner may later provide an adapter, but we recommend using `Postburner::Job` classes
75
- directyly.
250
+ directly.
76
251
 
77
252
  Add jobs to `app/jobs/`. There currently is no generator.
253
+
78
254
  ```ruby
79
255
  # app/jobs/run_donation.rb
80
-
81
256
  class RunDonation < Postburner::Job
82
257
  queue 'critical'
83
258
  queue_priority 0 # 0 is highest priority
@@ -88,6 +263,34 @@ class RunDonation < Postburner::Job
88
263
  # also have access to self.args
89
264
  end
90
265
  end
266
+ ```
267
+
268
+ ### Comparison to Backburner
269
+
270
+ Compared to plain [Backburner](https://github.com/nesquena/backburner),
271
+ Postburner adds:
272
+ - Database Jobs for inspection, linking, auditing, removal (and deletion)
273
+ - Direct access to associated [Beanstalk](https://beanstalkd.github.io/) (via [beaneater](https://github.com/beanstalkd/beaneater))
274
+ - Job Statistics (lag, attempts, logs, tracked errors)
275
+ - Convenience methods to clear tubes, stats, and connections for Beanstalk.
276
+
277
+ Otherwise, Postburner tries to be a super simple layer on `Backburner::Queue`
278
+ and `ActiveRecord`. Every tool with either of those are available in
279
+ `Postburner::Job`s.
280
+
281
+ Comes with a mountable interface that can be password protected with whatever
282
+ authentication you use in your project.
283
+
284
+ ### Comparison to Que
285
+
286
+ Postburner meant to be a replacement/upgrade for [Que](https://github.com/que-rb/que).
287
+ However, if you need something faster and backed with ACID compliance, check out Que.
288
+
289
+ Postburner has some additional features such as retained jobs after processing,
290
+ stats, per job logging, etc.
291
+
292
+ Postburner is meant to be simpler than `Que`. Que is incredible, but jobs should
293
+ be simple so the logic and history can be transparent.
91
294
 
92
295
  ## Contributing
93
296
  Submit a pull request. Follow conventions of the project. Be nice.
@@ -102,7 +305,6 @@ Submit a pull request. Follow conventions of the project. Be nice.
102
305
  - Job generator
103
306
  - Build file in app/jobs
104
307
  - Inherit from Postburner::Job
105
- - Job generator
106
308
  - Add before/after/around hooks
107
309
  - Add destroy, and remove actions on show page
108
310
  - Clear tubes.
@@ -112,5 +314,23 @@ Submit a pull request. Follow conventions of the project. Be nice.
112
314
  - Add logging with Job.args in backburner logs
113
315
  - MAYBE - ActiveJob adapter
114
316
 
317
+
318
+ ### Running in Development
319
+
320
+ ```
321
+ cd test/dummy
322
+ bundle exec backburner
323
+ ```
324
+
325
+ ### Releasing
326
+
327
+ 1. `gem bump -v minor -t`
328
+ Where <minor> can be: major|minor|patch|pre|release or a version number
329
+ 2. Edit `CHANGELOG.md` with details from `git log --oneline`
330
+ 3. `git commit --amend`
331
+ 4. `gem release -k nac -p`
332
+ Where <nac> is an authorized key with push capabilities.
333
+
334
+
115
335
  ## License
116
336
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,4 +1,17 @@
1
1
  module Postburner
2
+ # Must implement a perform method, if an exception is raised the job
3
+ # doesn't complete.
4
+ #
5
+ # Job won't run unless queued_at is set, and is set to a time prior to
6
+ # the time the job runs.
7
+ #
8
+ # TODO Mailer uses ActiveJob::Arguments... probably should use that here
9
+ # as well. Decided how to migrate existing jobs or allow both - Opt to
10
+ # allow both: rescue from ActiveJob::DeserializationError and use the
11
+ # plain hash, probably log it too.
12
+ #
13
+ # Add `cancelled_at` that blocks jobs performing if present.
14
+ #
2
15
  class Job < ApplicationRecord
3
16
  include Backburner::Queue
4
17
 
@@ -17,6 +30,8 @@ module Postburner
17
30
  def queue!(options={})
18
31
  return if self.queued_at.present? && self.bkid.present?
19
32
 
33
+ self.save!
34
+
20
35
  case
21
36
  when options[:at].present?
22
37
  # this is rudimentary, add error handling
@@ -33,14 +48,15 @@ module Postburner
33
48
  # tube: backburner.worker.queue.backburner-jobs
34
49
  #
35
50
  def self.perform(id, _={})
51
+ job = nil
36
52
  begin
37
53
  job = self.find(id)
38
- job.perform!(job.args)
39
54
  rescue ActiveRecord::RecordNotFound => e
40
55
  Rails.logger.warn <<-MSG
41
56
  [Postburner::Job] [#{id}] Not Found.
42
57
  MSG
43
58
  end
59
+ job&.perform!(job.args)
44
60
  end
45
61
 
46
62
  def perform!(args={})
@@ -55,45 +71,62 @@ module Postburner
55
71
  )
56
72
 
57
73
  begin
74
+ if self.queued_at.nil?
75
+ self.log! "Not Queued", level: :error
76
+ return
77
+ end
78
+
79
+ if self.queued_at > Time.zone.now
80
+ self.log! "Future Queued", level: :error
81
+ return
82
+ end
83
+
84
+ if self.processed_at.present?
85
+ self.log! "Already Processed", level: :error
86
+ self.delete!
87
+ return
88
+ end
89
+
58
90
  if self.removed_at.present?
59
- self.log "Removed", level: :error
60
- update_column :logs, self.logs
91
+ self.log! "Removed", level: :error
61
92
  return
62
93
  end
63
94
 
64
95
  if self.run_at && self.run_at > Time.zone.now
65
96
  response = self.insert! delay: self.run_at - Time.zone.now
66
- self.log "PREMATURE; RE-INSERTED: #{response}"
67
- update_column :logs, self.logs
97
+ self.log! "PREMATURE; RE-INSERTED: #{response}"
68
98
  return
69
99
  end
70
100
 
71
- self.log('START')
101
+ self.log!('START')
72
102
 
73
103
  self.perform(args)
74
104
 
75
- self.log('DONE')
105
+ self.log!('DONE')
106
+
107
+ begin
108
+ now = Time.zone.now
109
+ _duration = (now - self.processing_at) * 1000 rescue nil
110
+ self.update_columns(
111
+ processed_at: now,
112
+ duration: _duration,
113
+ errata: self.errata,
114
+ error_count: self.errata.length,
115
+ logs: self.logs,
116
+ log_count: self.logs.length,
117
+ )
118
+ rescue Exception => e
119
+ self.log_exception!(e)
120
+ self.log! '[Postburner] Could not set data after processing.'
121
+ # TODO README doesn't retry if Postburner is to blame
122
+ end
76
123
 
77
- rescue Exception => e
78
- self.log_exception(e)
124
+ rescue Exception => exception
125
+ self.log_exception!(exception)
126
+ self.log! '[Postburner] Exception raised during perform prevented completion.'
127
+ raise exception
79
128
  end
80
129
 
81
- begin
82
- now = Time.zone.now
83
- _duration = (now - self.processing_at) * 1000 rescue nil
84
- self.update_columns(
85
- processed_at: now,
86
- duration: _duration,
87
- errata: self.errata,
88
- error_count: self.errata.length,
89
- logs: self.logs,
90
- log_count: self.logs.length,
91
- )
92
- rescue Exception => e
93
- raise e if Rails.env.development? || Rails.env.production?
94
- self.log_exception(e)
95
- update_column :errata, self.errata
96
- end
97
130
  end
98
131
 
99
132
  def delete!
@@ -115,9 +148,12 @@ module Postburner
115
148
  end
116
149
 
117
150
  def remove!
118
- return false if self.attempts.any?
119
- self.delete!
120
- self.update_column(removed_at: Time.zone.now)
151
+ if self.beanstalk_job
152
+ self.delete!
153
+ self.update_column(:removed_at, Time.zone.now)
154
+ else
155
+ false
156
+ end
121
157
  end
122
158
 
123
159
  def beanstalk_job
@@ -145,6 +181,11 @@ module Postburner
145
181
  ]
146
182
  end
147
183
 
184
+ def log_exception!(exception)
185
+ self.log_exception(exception)
186
+ self.update_column :errata, self.errata
187
+ end
188
+
148
189
  def log(message, options={})
149
190
  options[:level] ||= :info
150
191
  options[:level] = :error unless LOG_LEVELS.member?(options[:level])
@@ -156,10 +197,19 @@ module Postburner
156
197
  ]
157
198
  end
158
199
 
200
+ def log!(message, options={})
201
+ self.log(message, options)
202
+ self.update_column :logs, self.logs
203
+ end
204
+
159
205
  private
160
206
 
161
207
  def insert!(options={})
162
- response = Backburner::Worker.enqueue(Postburner::Job, self.id, options)
208
+ response = Backburner::Worker.enqueue(
209
+ Postburner::Job,
210
+ self.id,
211
+ options
212
+ )
163
213
 
164
214
  self.log("QUEUED: #{response}")
165
215
 
@@ -1,14 +1,14 @@
1
1
  module Postburner
2
2
  # Send a mailer, tracked.
3
3
  #
4
- # Postburner::Mailer.deliver(UserMailer, :welcome, user_id: 1)
5
- # Postburner::Mailer.deliver(UserMailer, :welcome, user_id: 1).queue! at: Time.zone.now + 1.day
6
- # Postburner::Mailer.deliver(UserMailer, :welcome, user_id: 1).queue! delay: 5.minutes
4
+ # Postburner::Mailer.deliver(UserMailer, :welcome).with(user_id: 1)
5
+ # Postburner::Mailer.deliver(UserMailer, :welcome).with(user_id: 1).queue! at: Time.zone.now + 1.day
6
+ # Postburner::Mailer.deliver(UserMailer, :welcome).with(user_id: 1).queue! delay: 5.minutes
7
7
  class Mailer < Job
8
8
  #queue 'mailers'
9
9
 
10
- def self.deliver!(mailer, action)
11
- job = self.create!(
10
+ def self.delivery(mailer, action)
11
+ job = self.new(
12
12
  args: {
13
13
  mailer: mailer.to_s,
14
14
  action: action.to_s,
@@ -17,9 +17,62 @@ module Postburner
17
17
  job
18
18
  end
19
19
 
20
- def process(args)
21
- cls = args['mailer'].constantize
22
- cls.send(args['action']).deliver_now
20
+ def self.delivery!(mailer, action)
21
+ job = self.delivery(mailer, action)
22
+ job.save!
23
+ job
24
+ end
25
+
26
+ # Similar to ActionMailer #with - set the parameters
27
+ #
28
+ def with(params={})
29
+ self.args.merge!(
30
+ 'params' => ActiveJob::Arguments.serialize(params)
31
+ )
32
+ self
33
+ end
34
+
35
+ def with!(params={})
36
+ self.with(params)
37
+ self.save!
38
+ self
39
+ end
40
+
41
+ # Build the mail but don't send.
42
+ #
43
+ # Optional `args` argument for testing convenience.
44
+ #
45
+ def assemble
46
+ mail = self.mailer.with(self.params).send(self.action)
47
+ mail
48
+ end
49
+
50
+ # Get the mailer class.
51
+ #
52
+ def mailer
53
+ self.args['mailer'].constantize
54
+ end
55
+
56
+ # Get the mailer action as a symbol.
57
+ #
58
+ def action
59
+ self.args['action']&.to_sym
60
+ end
61
+
62
+ # Get the deserialized params.
63
+ #
64
+ def params
65
+ ActiveJob::Arguments.deserialize(self.args['params']).to_h
66
+ end
67
+
68
+ def perform(args)
69
+ self.log! "Building"
70
+ mail = self.assemble
71
+
72
+ self.log! "Delivering"
73
+ mail.deliver_now
74
+
75
+ self.log! "Delivered"
23
76
  end
24
77
  end
25
78
  end
@@ -1,3 +1,3 @@
1
1
  module Postburner
2
- VERSION = '0.3.1'
2
+ VERSION = '0.5.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postburner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-07 00:00:00.000000000 Z
11
+ date: 2021-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -128,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
128
  - !ruby/object:Gem::Version
129
129
  version: '0'
130
130
  requirements: []
131
- rubygems_version: 3.1.4
131
+ rubygems_version: 3.1.6
132
132
  signing_key:
133
133
  specification_version: 4
134
134
  summary: Postgres backed beanstalkd queue via backburner