postburner 0.3.1 → 0.5.0

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