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 +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +251 -31
- data/app/models/postburner/job.rb +79 -29
- data/app/models/postburner/mailer.rb +61 -8
- data/lib/postburner/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffbffc2cebbe2e83bfff21178b71d0b205756cd6ef05c6dc30c8029d073c70d7
|
4
|
+
data.tar.gz: 68136a8de901340817dcd60e0fbd3b6794eb6dea2f8da386af138576dbba6334
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
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
|
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
|
-
#
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =>
|
78
|
-
self.log_exception(
|
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
|
-
|
119
|
-
|
120
|
-
|
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(
|
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
|
5
|
-
# Postburner::Mailer.deliver(UserMailer, :welcome
|
6
|
-
# Postburner::Mailer.deliver(UserMailer, :welcome
|
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.
|
11
|
-
job = self.
|
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
|
21
|
-
|
22
|
-
|
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
|
data/lib/postburner/version.rb
CHANGED
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.
|
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-
|
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.
|
131
|
+
rubygems_version: 3.1.6
|
132
132
|
signing_key:
|
133
133
|
specification_version: 4
|
134
134
|
summary: Postgres backed beanstalkd queue via backburner
|