postburner 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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