postburner 0.3.3 → 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 +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +251 -31
- data/app/models/postburner/job.rb +2 -2
- data/app/models/postburner/mailer.rb +30 -7
- 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: 6faa3078340ee2bc8d90e931ee1db203114e32ff69b288ec69340e8b86a987cd
|
4
|
+
data.tar.gz: 0a2ddf78a320e9b01c26a0e3fbd3158b78d37a89bca04a5fdd8c64b70eada1a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5253309eb7aff502623040d49e923faff7c91df6aac407ec7a4e306a8317b1363db43a4b0408eb20fbdad6ee017ad68489480ac50d7e2ac68a612a1337488457
|
7
|
+
data.tar.gz: 49d0253fe3ecde9cfd4de8b48a2ce95997245bea4310f7c751ccca3685fea8a42b29310a8058f222031ee8aa91f6ec61f990ec5c330157e39853c95830236cfa
|
data/CHANGELOG.md
CHANGED
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,13 +1,13 @@
|
|
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.deliver
|
10
|
+
def self.deliver(mailer, action)
|
11
11
|
job = self.create!(
|
12
12
|
args: {
|
13
13
|
mailer: mailer.to_s,
|
@@ -17,9 +17,32 @@ module Postburner
|
|
17
17
|
job
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# Similar to ActionMailer #with - set the parameters
|
21
|
+
#
|
22
|
+
def with(params={})
|
23
|
+
self.args.merge!(
|
24
|
+
params: ActiveJob::Arguments.serialize(params)
|
25
|
+
)
|
26
|
+
self.save!
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Build the mail but don't send.
|
31
|
+
#
|
32
|
+
def assemble(args=nil)
|
33
|
+
_args = args || self.args
|
34
|
+
|
35
|
+
cls = _args['mailer'].constantize
|
36
|
+
|
37
|
+
mail = cls.
|
38
|
+
with(ActiveJob::Arguments.deserialize(_args['params']).to_h).
|
39
|
+
send(_args['action'])
|
40
|
+
|
41
|
+
mail
|
42
|
+
end
|
43
|
+
|
44
|
+
def perform(args)
|
45
|
+
self.assemble(args).deliver_now
|
23
46
|
end
|
24
47
|
end
|
25
48
|
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.4.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-12 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
|