postburner 0.7.1 → 0.8.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 +17 -0
- data/README.md +18 -0
- data/app/models/postburner/job.rb +21 -17
- data/lib/postburner/tube.rb +53 -0
- data/lib/postburner/version.rb +1 -1
- data/lib/postburner.rb +1 -0
- metadata +3 -3
- data/app/concerns/postburner/callbacks.rb +0 -286
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3f5758fde9443c7c094a85825c343aa003fd43a969323d549fe631d3c114fd8
|
4
|
+
data.tar.gz: aa30ba2e1ef5669bc9dd86243553dcc3f89c5dfa0a084c154afd313919df82db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f87f62fdca9594f365fb1641a3c0d83adc78271a0ac22e4b711e684cf02ba7fa5e9ad51c0ec2eac999ee62ac95d998bd7dccf3ef33e64856b77b40fa39329a5
|
7
|
+
data.tar.gz: 9e518552995537a13204210f5fdffb76a7d709a64c0064dec45a0b02150c871774e4ed0f7c82da90ac2fd3d76c313577f70420a95461d426b21fb20abaf428e5
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.8.0 - 2022-11-13
|
4
|
+
|
5
|
+
### Added
|
6
|
+
- add Postburner::Tube for Beaneater job introspection.
|
7
|
+
- add note about tube names and hyphens/dashes to README.
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
- fix Backburner::Queue methods in subclasses for queue selection, etc.
|
11
|
+
|
12
|
+
## v0.7.1 - 2022-10-30
|
13
|
+
|
14
|
+
### Required Changes
|
15
|
+
- rename `enqueue` callbacks to `insert`.
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
- convert to ActiveModel callbacks.
|
19
|
+
|
3
20
|
## v0.7.1 - 2022-10-30
|
4
21
|
|
5
22
|
### Changed
|
data/README.md
CHANGED
@@ -203,6 +203,24 @@ to add your own authentication or changes - or just create your own routes, cont
|
|
203
203
|
[Override the views](https://guides.rubyonrails.org/engines.html#overriding-views) to make them
|
204
204
|
prettier - or follow the suggestion above and use your own.
|
205
205
|
|
206
|
+
## Known Issues
|
207
|
+
|
208
|
+
1. Beaneater and/or Beanstalkd seems to transform a `tube` `name` with hyphens to
|
209
|
+
underscores upon instrospection of `stats`. See example. Reccommend using
|
210
|
+
names without hyphens / dashes.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
(main):001:0> Postburner.connection.tubes["backburner.worker.queue.cat-dog"].put("{}", delay: 1.week.to_i)
|
214
|
+
=> {:status=>"INSERTED", :id=>"9"}
|
215
|
+
irb(main):002:0> Postburner.connection.jobs.find(9)
|
216
|
+
=> #<Beaneater::Job id=9 body="{}">
|
217
|
+
irb(main):003:0> Postburner.connection.jobs.find(9).stats
|
218
|
+
=> #<Beaneater::StatStruct id=9, tube="backburner.worker.queue.cat_dog", state="delayed", pri=65536, age=23, delay=604800, ttr=120, time_left=604776, file=0, reserves=0, timeouts=0, releases=0, buries=0, kicks=0>
|
219
|
+
#
|
220
|
+
# NOTE 'cat-dog' on line 1 and 'cat_dog' on line 3.
|
221
|
+
#
|
222
|
+
```
|
223
|
+
|
206
224
|
## Installation
|
207
225
|
|
208
226
|
First [install beanstalkd](https://beanstalkd.github.io/download.html). On Debian-based systems, that goes like this:
|
@@ -16,7 +16,11 @@ module Postburner
|
|
16
16
|
#
|
17
17
|
class Job < ApplicationRecord
|
18
18
|
include Backburner::Queue
|
19
|
-
|
19
|
+
|
20
|
+
define_model_callbacks :insert
|
21
|
+
define_model_callbacks :attempt
|
22
|
+
define_model_callbacks :processing
|
23
|
+
define_model_callbacks :processed, only: :after
|
20
24
|
|
21
25
|
LOG_LEVELS = [
|
22
26
|
:debug,
|
@@ -51,9 +55,7 @@ module Postburner
|
|
51
55
|
|
52
56
|
@_insert_options = options
|
53
57
|
|
54
|
-
|
55
|
-
self.save!
|
56
|
-
end
|
58
|
+
self.save!
|
57
59
|
end
|
58
60
|
|
59
61
|
def requeue!(options={})
|
@@ -83,7 +85,7 @@ module Postburner
|
|
83
85
|
end
|
84
86
|
|
85
87
|
def perform!(args={})
|
86
|
-
|
88
|
+
_run_attempt_callbacks do
|
87
89
|
self.attempting
|
88
90
|
|
89
91
|
self.update_columns(
|
@@ -124,7 +126,7 @@ module Postburner
|
|
124
126
|
|
125
127
|
self.log!("START (bkid #{self.bkid})")
|
126
128
|
|
127
|
-
|
129
|
+
_run_processing_callbacks do
|
128
130
|
begin
|
129
131
|
self.perform(args)
|
130
132
|
rescue Exception => exception
|
@@ -140,7 +142,7 @@ module Postburner
|
|
140
142
|
now = Time.zone.now
|
141
143
|
_duration = (now - self.processing_at) * 1000 rescue nil
|
142
144
|
|
143
|
-
|
145
|
+
_run_processed_callbacks do
|
144
146
|
persist_metadata!(
|
145
147
|
processed_at: now,
|
146
148
|
duration: _duration,
|
@@ -269,16 +271,18 @@ module Postburner
|
|
269
271
|
def insert!(options={})
|
270
272
|
response = nil
|
271
273
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
274
|
+
_run_insert_callbacks do
|
275
|
+
Job.transaction do
|
276
|
+
response = Backburner::Worker.enqueue(
|
277
|
+
self.class,
|
278
|
+
self.id,
|
279
|
+
options
|
280
|
+
)
|
281
|
+
|
282
|
+
persist_metadata!(
|
283
|
+
bkid: response[:id],
|
284
|
+
)
|
285
|
+
end
|
282
286
|
end
|
283
287
|
|
284
288
|
self.log("QUEUED: #{response}")
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Postburner
|
2
|
+
class Tube
|
3
|
+
def initialize(tube)
|
4
|
+
@tube = tube
|
5
|
+
end
|
6
|
+
|
7
|
+
# Get all tubes as Postburner::Tube instances.
|
8
|
+
#
|
9
|
+
def self.all
|
10
|
+
Postburner.connection.tubes.all.map { |tube| self.new(tube) }
|
11
|
+
end
|
12
|
+
|
13
|
+
# Get all peeked ids across all known tubes.
|
14
|
+
#
|
15
|
+
def self.peek_ids
|
16
|
+
self.all.map(&:peek_ids).flatten.sort
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get all peeked ids.
|
20
|
+
#
|
21
|
+
def peek_ids
|
22
|
+
[ :buried, :ready, :delayed ].map { |type| @tube.peek(type) }.
|
23
|
+
reject(&:nil?).map(&:id).map(&:to_i)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Get paginated array of jobs.
|
27
|
+
#
|
28
|
+
# Attempts to do this efficiently as possible, by peeking at known
|
29
|
+
# ids and exiting when count has been fulfilled.
|
30
|
+
#
|
31
|
+
# Just pass the last known id to after for the next batch.
|
32
|
+
#
|
33
|
+
def jobs(count=20, limit: 1000, after: nil)
|
34
|
+
stats = @tube.stats
|
35
|
+
jobs = Array.new
|
36
|
+
|
37
|
+
min_known = (
|
38
|
+
peek_ids.any? ? self.peek_ids.min : self.class.peek_ids.min
|
39
|
+
).to_i
|
40
|
+
min = after ? after + 1 : min_known
|
41
|
+
max = min + limit
|
42
|
+
|
43
|
+
for i in min..max
|
44
|
+
job = @tube.client.jobs.find(i)
|
45
|
+
jobs << job if job && stats[:name] == job.stats[:tube]
|
46
|
+
break if jobs.length >= count
|
47
|
+
end
|
48
|
+
|
49
|
+
return jobs
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/lib/postburner/version.rb
CHANGED
data/lib/postburner.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.8.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: 2022-
|
11
|
+
date: 2022-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -79,7 +79,6 @@ files:
|
|
79
79
|
- Rakefile
|
80
80
|
- app/assets/config/postburner_manifest.js
|
81
81
|
- app/assets/stylesheets/postburner/application.css
|
82
|
-
- app/concerns/postburner/callbacks.rb
|
83
82
|
- app/controllers/postburner/application_controller.rb
|
84
83
|
- app/controllers/postburner/jobs_controller.rb
|
85
84
|
- app/controllers/postburner/static_controller.rb
|
@@ -99,6 +98,7 @@ files:
|
|
99
98
|
- lib/generators/postburner/install/templates/migrations/create_postburner_jobs.rb.erb
|
100
99
|
- lib/postburner.rb
|
101
100
|
- lib/postburner/engine.rb
|
101
|
+
- lib/postburner/tube.rb
|
102
102
|
- lib/postburner/version.rb
|
103
103
|
- lib/tasks/postburner_tasks.rake
|
104
104
|
homepage: https://gitlab.nearapogee.com/opensource/postburner
|
@@ -1,286 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_support/callbacks"
|
4
|
-
require "active_support/core_ext/object/with_options"
|
5
|
-
require "active_support/core_ext/module/attribute_accessors"
|
6
|
-
|
7
|
-
module Postburner
|
8
|
-
# = Postburner Job Callbacks
|
9
|
-
#
|
10
|
-
# Postburner Job provides hooks during the life cycle of a job. Callbacks allow you
|
11
|
-
# to trigger logic during this cycle. In called order, available callbacks are:
|
12
|
-
#
|
13
|
-
# * <tt>before_enqueue</tt>
|
14
|
-
# * <tt>after_enqueue</tt>
|
15
|
-
# * <tt>before_attempt</tt>
|
16
|
-
# * <tt>before_processing</tt>
|
17
|
-
# * <tt>after_processing</tt>
|
18
|
-
# * <tt>after_processed</tt>
|
19
|
-
# * <tt>after_attempt</tt>
|
20
|
-
#
|
21
|
-
# Around callbacks are also defined:
|
22
|
-
# * <tt>around_enqueue</tt>
|
23
|
-
# * <tt>around_attempt</tt>
|
24
|
-
# * <tt>around_processing</tt>
|
25
|
-
#
|
26
|
-
# NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
|
27
|
-
#
|
28
|
-
module Callbacks
|
29
|
-
extend ActiveSupport::Concern
|
30
|
-
include ActiveSupport::Callbacks
|
31
|
-
|
32
|
-
included do
|
33
|
-
cattr_accessor :skip_after_callbacks_if_terminated,
|
34
|
-
instance_accessor: false,
|
35
|
-
default: false
|
36
|
-
|
37
|
-
with_options(skip_after_callbacks_if_terminated: skip_after_callbacks_if_terminated) do
|
38
|
-
define_callbacks :enqueue
|
39
|
-
define_callbacks :attempt
|
40
|
-
define_callbacks :processing
|
41
|
-
define_callbacks :processed
|
42
|
-
end
|
43
|
-
end
|
44
|
-
module ClassMethods
|
45
|
-
def inherited(klass)
|
46
|
-
klass.get_callbacks(:enqueue).
|
47
|
-
config[:skip_after_callbacks_if_terminated] =
|
48
|
-
skip_after_callbacks_if_terminated
|
49
|
-
klass.get_callbacks(:processing).
|
50
|
-
config[:skip_after_callbacks_if_terminated] =
|
51
|
-
skip_after_callbacks_if_terminated
|
52
|
-
klass.get_callbacks(:attempt).
|
53
|
-
config[:skip_after_callbacks_if_terminated] =
|
54
|
-
skip_after_callbacks_if_terminated
|
55
|
-
klass.get_callbacks(:processed).
|
56
|
-
config[:skip_after_callbacks_if_terminated] =
|
57
|
-
skip_after_callbacks_if_terminated
|
58
|
-
super
|
59
|
-
end
|
60
|
-
|
61
|
-
# Defines a callback that will get called right before the
|
62
|
-
# job starts and any metadata is persisted.
|
63
|
-
#
|
64
|
-
# class VideoProcessJob < Postburner::Base
|
65
|
-
#
|
66
|
-
# before_attempt do |job|
|
67
|
-
# $statsd.increment "attempting-video-job.try"
|
68
|
-
# end
|
69
|
-
#
|
70
|
-
# def perform(video_id)
|
71
|
-
# Video.find(video_id).process
|
72
|
-
# end
|
73
|
-
# end
|
74
|
-
#
|
75
|
-
def before_attempt(*filters, &blk)
|
76
|
-
set_callback(:attempt, :before, *filters, &blk)
|
77
|
-
end
|
78
|
-
|
79
|
-
# Defines a callback that will get called right after the
|
80
|
-
# job finishes and all metadata is persisted.
|
81
|
-
#
|
82
|
-
# This isn't called unless the attempt finishes without error,
|
83
|
-
# though this is subject to change in the future
|
84
|
-
#
|
85
|
-
# class VideoProcessJob < Postburner::Base
|
86
|
-
#
|
87
|
-
# before_attempt do |job|
|
88
|
-
# $statsd.increment "attempt-complete-video-job.try"
|
89
|
-
# end
|
90
|
-
#
|
91
|
-
# def perform(video_id)
|
92
|
-
# Video.find(video_id).process
|
93
|
-
# end
|
94
|
-
# end
|
95
|
-
#
|
96
|
-
def after_attempt(*filters, &blk)
|
97
|
-
set_callback(:attempt, :after, *filters, &blk)
|
98
|
-
end
|
99
|
-
|
100
|
-
# Defines a callback that will get called around the attempt
|
101
|
-
# of the job.
|
102
|
-
#
|
103
|
-
# class VideoProcessJob < Postburner::Base
|
104
|
-
#
|
105
|
-
# around_enqueue do |job, block|
|
106
|
-
# $statsd.time "video-job.process" do
|
107
|
-
# block.call
|
108
|
-
# end
|
109
|
-
# end
|
110
|
-
#
|
111
|
-
# def perform(video_id)
|
112
|
-
# Video.find(video_id).process
|
113
|
-
# end
|
114
|
-
# end
|
115
|
-
#
|
116
|
-
def around_attempt(*filters, &blk)
|
117
|
-
set_callback(:attempt, :around, *filters, &blk)
|
118
|
-
end
|
119
|
-
|
120
|
-
# Defines a callback that will get called right before the
|
121
|
-
# job's perform method is executed.
|
122
|
-
#
|
123
|
-
# class VideoProcessJob < Postburner::Base
|
124
|
-
#
|
125
|
-
# before_processing do |job|
|
126
|
-
# UserMailer.notify_video_started_processing(job.arguments.first)
|
127
|
-
# end
|
128
|
-
#
|
129
|
-
# def perform(video_id)
|
130
|
-
# Video.find(video_id).process
|
131
|
-
# end
|
132
|
-
# end
|
133
|
-
#
|
134
|
-
def before_processing(*filters, &blk)
|
135
|
-
set_callback(:processing, :before, *filters, &blk)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Defines a callback that will get called right after the
|
139
|
-
# job's perform method has finished.
|
140
|
-
#
|
141
|
-
# class VideoProcessJob < Postburner::Base
|
142
|
-
#
|
143
|
-
# after_processing do |job|
|
144
|
-
# UserMailer.notify_video_processed(job.arguments.first)
|
145
|
-
# end
|
146
|
-
#
|
147
|
-
# def perform(video_id)
|
148
|
-
# Video.find(video_id).process
|
149
|
-
# end
|
150
|
-
# end
|
151
|
-
#
|
152
|
-
def after_processing(*filters, &blk)
|
153
|
-
set_callback(:processing, :after, *filters, &blk)
|
154
|
-
end
|
155
|
-
|
156
|
-
# Defines a callback that will get called around the job's perform method.
|
157
|
-
#
|
158
|
-
# class VideoProcessJob < Postburner::Base
|
159
|
-
#
|
160
|
-
# around_processing do |job, block|
|
161
|
-
# UserMailer.notify_video_started_processing(job.arguments.first)
|
162
|
-
# block.call
|
163
|
-
# UserMailer.notify_video_processed(job.arguments.first)
|
164
|
-
# end
|
165
|
-
#
|
166
|
-
# def perform(video_id)
|
167
|
-
# Video.find(video_id).process
|
168
|
-
# end
|
169
|
-
# end
|
170
|
-
#
|
171
|
-
# You can access the return value of the job only if the execution wasn't halted.
|
172
|
-
#
|
173
|
-
# class VideoProcessJob < Postburner::Base
|
174
|
-
# around_processing do |job, block|
|
175
|
-
# value = block.call
|
176
|
-
# puts value # => "Hello World!"
|
177
|
-
# end
|
178
|
-
#
|
179
|
-
# def perform
|
180
|
-
# "Hello World!"
|
181
|
-
# end
|
182
|
-
# end
|
183
|
-
#
|
184
|
-
def around_processing(*filters, &blk)
|
185
|
-
set_callback(:processing, :around, *filters, &blk)
|
186
|
-
end
|
187
|
-
|
188
|
-
# Defines a callback that will get called right after the
|
189
|
-
# job's processed_at timestamp has been persisted, marking the
|
190
|
-
# job as successfully completed, i.e. no errors raised.
|
191
|
-
#
|
192
|
-
# This is rather similar to after_processing but all of the
|
193
|
-
# job's metadata has been set.
|
194
|
-
#
|
195
|
-
# class VideoProcessJob < Postburner::Base
|
196
|
-
#
|
197
|
-
# after_processed do |job|
|
198
|
-
# UserMailer.notify_video_processed(job.arguments.first)
|
199
|
-
# end
|
200
|
-
#
|
201
|
-
# def perform(video_id)
|
202
|
-
# Video.find(video_id).process
|
203
|
-
# end
|
204
|
-
# end
|
205
|
-
#
|
206
|
-
def after_processed(*filters, &blk)
|
207
|
-
set_callback(:processed, :after, *filters, &blk)
|
208
|
-
end
|
209
|
-
|
210
|
-
# Defines a callback that will get called right before the
|
211
|
-
# job is enqueued.
|
212
|
-
#
|
213
|
-
# class VideoProcessJob < Postburner::Base
|
214
|
-
#
|
215
|
-
# before_enqueue do |job|
|
216
|
-
# $statsd.increment "enqueue-video-job.try"
|
217
|
-
# end
|
218
|
-
#
|
219
|
-
# def perform(video_id)
|
220
|
-
# Video.find(video_id).process
|
221
|
-
# end
|
222
|
-
# end
|
223
|
-
#
|
224
|
-
def before_enqueue(*filters, &blk)
|
225
|
-
set_callback(:enqueue, :before, *filters, &blk)
|
226
|
-
end
|
227
|
-
|
228
|
-
# Defines a callback that will get called right after the
|
229
|
-
# job is enqueued.
|
230
|
-
#
|
231
|
-
# class VideoProcessJob < Postburner::Base
|
232
|
-
#
|
233
|
-
# after_enqueue do |job|
|
234
|
-
# $statsd.increment "enqueue-video-job.success"
|
235
|
-
# end
|
236
|
-
#
|
237
|
-
# def perform(video_id)
|
238
|
-
# Video.find(video_id).process
|
239
|
-
# end
|
240
|
-
# end
|
241
|
-
#
|
242
|
-
def after_enqueue(*filters, &blk)
|
243
|
-
set_callback(:enqueue, :after, *filters, &blk)
|
244
|
-
end
|
245
|
-
|
246
|
-
# Defines a callback that will get called around the enqueuing
|
247
|
-
# of the job.
|
248
|
-
#
|
249
|
-
# class VideoProcessJob < Postburner::Base
|
250
|
-
#
|
251
|
-
# around_enqueue do |job, block|
|
252
|
-
# $statsd.time "video-job.process" do
|
253
|
-
# block.call
|
254
|
-
# end
|
255
|
-
# end
|
256
|
-
#
|
257
|
-
# def perform(video_id)
|
258
|
-
# Video.find(video_id).process
|
259
|
-
# end
|
260
|
-
# end
|
261
|
-
#
|
262
|
-
def around_enqueue(*filters, &blk)
|
263
|
-
set_callback(:enqueue, :around, *filters, &blk)
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
private
|
268
|
-
|
269
|
-
# NOTE processed / attempt exclueded here -- intentionally
|
270
|
-
#
|
271
|
-
def halted_callback_hook(_filter, name) # :nodoc:
|
272
|
-
return super unless %i(enqueue processing).include?(name.to_sym)
|
273
|
-
callbacks = public_send("_#{name}_callbacks")
|
274
|
-
|
275
|
-
if !self.class.skip_after_callbacks_if_terminated && callbacks.any? { |c| c.kind == :after }
|
276
|
-
ActiveSupport::Deprecation.warn(<<~EOM)
|
277
|
-
In Rails 7.0, `after_enqueue`/`after_work` callbacks no longer run if `before_enqueue`/`before_work` respectively halts with `throw :abort`.
|
278
|
-
To enable this behavior, uncomment the `config.active_job.skip_after_callbacks_if_terminated` config
|
279
|
-
in the new 6.1 framework defaults initializer.
|
280
|
-
EOM
|
281
|
-
end
|
282
|
-
|
283
|
-
super
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|