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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74d577811ded71db9296138442288dd53a0eb46718b8980564a84032c3a7b564
4
- data.tar.gz: b97fb1adb55232e5c2293d88c852ab496f3519ad740b2f0d5df8d68f7d663e97
3
+ metadata.gz: b3f5758fde9443c7c094a85825c343aa003fd43a969323d549fe631d3c114fd8
4
+ data.tar.gz: aa30ba2e1ef5669bc9dd86243553dcc3f89c5dfa0a084c154afd313919df82db
5
5
  SHA512:
6
- metadata.gz: 995fe1db553b3e2b698427eeb061a6e5463011ed29315dbd5280f8a1d4c46f6f1c4a15607b80c58d2ba393d896e15f38baa4581a616a758f7f57ffda8d57ac70
7
- data.tar.gz: d123415e6a7a4329a1897922ab6619a032fc5c61b501fb612dcfa9eb370ec45da97b3ff0787a2baf25101fd7fadee572c620f1fb32dbb202ee76c4f4e67a224d
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
- include Callbacks
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
- run_callbacks :enqueue do
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
- run_callbacks :attempt do
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
- run_callbacks :processing do
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
- run_callbacks :processed do
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
- Job.transaction do
273
- response = Backburner::Worker.enqueue(
274
- Postburner::Job,
275
- self.id,
276
- options
277
- )
278
-
279
- persist_metadata!(
280
- bkid: response[:id],
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
@@ -1,3 +1,3 @@
1
1
  module Postburner
2
- VERSION = '0.7.1'
2
+ VERSION = '0.8.0'
3
3
  end
data/lib/postburner.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "postburner/version"
2
2
  require "postburner/engine"
3
+ require "postburner/tube"
3
4
 
4
5
  module Postburner
5
6
 
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.7.1
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-10-30 00:00:00.000000000 Z
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