postburner 0.3.3 → 0.4.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 +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
|