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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b21ae5985bd9458b91095fe9a40370c6efe0a2d1903be46b47a0785dc6e0f73
4
- data.tar.gz: e7e3989d2805bc64815f6b586ba8e594b11963a7330e0d012a7671928b55576d
3
+ metadata.gz: 6faa3078340ee2bc8d90e931ee1db203114e32ff69b288ec69340e8b86a987cd
4
+ data.tar.gz: 0a2ddf78a320e9b01c26a0e3fbd3158b78d37a89bca04a5fdd8c64b70eada1a7
5
5
  SHA512:
6
- metadata.gz: af927556728f74e306075633a45851a51c4f26faa44f1c54901aa2c7a6f176e494b2c220d2040239e49c458a5cdc6c2e4ae19fd9d35548de1a2028f2a24c074a
7
- data.tar.gz: 22d1b312e5b44a21b9035ecaf6a732aa6bac2100244144ed1084bf1f1d83f170df1f378f262fabdc1c8ec2edf26c2c97d4cfd94b006c27992a5871261f09bb4d
6
+ metadata.gz: 5253309eb7aff502623040d49e923faff7c91df6aac407ec7a4e306a8317b1363db43a4b0408eb20fbdad6ee017ad68489480ac50d7e2ac68a612a1337488457
7
+ data.tar.gz: 49d0253fe3ecde9cfd4de8b48a2ce95997245bea4310f7c751ccca3685fea8a42b29310a8058f222031ee8aa91f6ec61f990ec5c330157e39853c95830236cfa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.4.0 - 2021-10-12
4
+
5
+ ### Added
6
+ - Change Job logging to persisted in perform.
7
+ - Update mailer job to use #with and support serializations.
8
+
3
9
  ## v0.3.3 - 2021-06-15
4
10
 
5
11
  ### 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).
@@ -72,11 +72,11 @@ module Postburner
72
72
  return
73
73
  end
74
74
 
75
- self.log('START')
75
+ self.log!('START')
76
76
 
77
77
  self.perform(args)
78
78
 
79
- self.log('DONE')
79
+ self.log!('DONE')
80
80
 
81
81
  begin
82
82
  now = Time.zone.now
@@ -1,13 +1,13 @@
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)
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
- def process(args)
21
- cls = args['mailer'].constantize
22
- cls.send(args['action']).deliver_now
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
@@ -1,3 +1,3 @@
1
1
  module Postburner
2
- VERSION = '0.3.3'
2
+ VERSION = '0.4.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.3
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-06-15 00:00:00.000000000 Z
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.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