postburner 1.0.0.pre.11 → 1.0.0.pre.12

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +961 -555
  3. data/app/concerns/postburner/commands.rb +1 -1
  4. data/app/concerns/postburner/execution.rb +11 -11
  5. data/app/concerns/postburner/insertion.rb +1 -1
  6. data/app/concerns/postburner/logging.rb +2 -2
  7. data/app/concerns/postburner/statistics.rb +1 -1
  8. data/app/models/postburner/job.rb +27 -4
  9. data/app/models/postburner/mailer.rb +1 -1
  10. data/app/models/postburner/schedule.rb +703 -0
  11. data/app/models/postburner/schedule_execution.rb +353 -0
  12. data/app/views/postburner/jobs/show.html.haml +3 -3
  13. data/lib/generators/postburner/install/install_generator.rb +1 -0
  14. data/lib/generators/postburner/install/templates/config/postburner.yml +15 -6
  15. data/lib/generators/postburner/install/templates/migrations/create_postburner_schedules.rb.erb +71 -0
  16. data/lib/postburner/active_job/adapter.rb +3 -3
  17. data/lib/postburner/active_job/payload.rb +5 -0
  18. data/lib/postburner/advisory_lock.rb +123 -0
  19. data/lib/postburner/configuration.rb +43 -7
  20. data/lib/postburner/connection.rb +7 -6
  21. data/lib/postburner/runner.rb +26 -3
  22. data/lib/postburner/scheduler.rb +427 -0
  23. data/lib/postburner/strategies/immediate_test_queue.rb +24 -7
  24. data/lib/postburner/strategies/nice_queue.rb +1 -1
  25. data/lib/postburner/strategies/null_queue.rb +2 -2
  26. data/lib/postburner/strategies/test_queue.rb +2 -2
  27. data/lib/postburner/time_helpers.rb +4 -2
  28. data/lib/postburner/tube.rb +9 -1
  29. data/lib/postburner/version.rb +1 -1
  30. data/lib/postburner/worker.rb +684 -0
  31. data/lib/postburner.rb +32 -13
  32. metadata +7 -3
  33. data/lib/postburner/workers/base.rb +0 -205
  34. data/lib/postburner/workers/worker.rb +0 -396
@@ -136,7 +136,7 @@ module Postburner
136
136
  def remove!
137
137
  return if self.removed_at
138
138
  self.delete!
139
- self.update_column(:removed_at, Time.zone.now)
139
+ self.update_column(:removed_at, Time.current)
140
140
  end
141
141
 
142
142
  end
@@ -23,17 +23,17 @@ module Postburner
23
23
  # queue strategy's {handle_perform!} method. This provides a unified API
24
24
  # for job execution regardless of strategy (async, test, or null).
25
25
  #
26
- # Called automatically by Backburner workers in production. Can also be
26
+ # Called automatically by Postburner workers in production. Can also be
27
27
  # called manually for test/null strategies to trigger execution.
28
28
  #
29
29
  # @param id [Integer] Job ID to execute
30
- # @param _ [Hash] Unused Backburner metadata parameter
30
+ # @param _ [Hash] Unused metadata parameter
31
31
  #
32
32
  # @return [void]
33
33
  #
34
- # @example Backburner automatic execution (production)
35
- # # Jobs execute in tube: backburner.worker.queue.backburner-jobs
36
- # # Backburner calls: Postburner::Job.perform(job_id)
34
+ # @example Worker automatic execution (production)
35
+ # # Jobs execute in configured Beanstalkd tube
36
+ # # Worker calls: Postburner::Job.perform(job_id)
37
37
  #
38
38
  # @example Manual execution with NullQueue
39
39
  # Postburner.null_strategy!
@@ -64,7 +64,7 @@ module Postburner
64
64
 
65
65
  # Executes the job with full lifecycle management and error handling.
66
66
  #
67
- # This is the main execution method called by Backburner workers or test strategies.
67
+ # This is the main execution method called by Postburner workers or test strategies.
68
68
  # Performs validation checks, executes callbacks, calls the subclass {#perform} method,
69
69
  # tracks timing and statistics, and handles errors.
70
70
  #
@@ -100,7 +100,7 @@ module Postburner
100
100
  attempts: self.attempts,
101
101
  attempt_count: self.attempts.length,
102
102
  lag: self.lag,
103
- processing_at: Time.zone.now,
103
+ processing_at: Time.current,
104
104
  )
105
105
 
106
106
  begin
@@ -109,7 +109,7 @@ module Postburner
109
109
  return
110
110
  end
111
111
 
112
- if self.queued_at > Time.zone.now
112
+ if self.queued_at > Time.current
113
113
  self.log! "Future Queued", level: :error
114
114
  return
115
115
  end
@@ -125,7 +125,7 @@ module Postburner
125
125
  return
126
126
  end
127
127
 
128
- if self.run_at && self.run_at.to_i > Time.zone.now.to_i
128
+ if self.run_at && self.run_at.to_i > Time.current.to_i
129
129
  Postburner.queue_strategy.handle_premature_perform(self)
130
130
  return
131
131
  end
@@ -145,7 +145,7 @@ module Postburner
145
145
  self.log!("DONE (bkid #{self.bkid})")
146
146
 
147
147
  begin
148
- now = Time.zone.now
148
+ now = Time.current
149
149
  _duration = (now - self.processing_at) * 1000 rescue nil
150
150
 
151
151
  run_callbacks :processed do
@@ -180,7 +180,7 @@ module Postburner
180
180
  # @api private
181
181
  #
182
182
  def attempting
183
- now = Time.zone.now
183
+ now = Time.current
184
184
  self.attempts << now
185
185
  self.attempting_at ||= now
186
186
  self.lag ||= (self.attempting_at - self.intended_at) * 1000 rescue nil
@@ -66,7 +66,7 @@ module Postburner
66
66
  raise AlreadyProcessed, "Processed at #{self.processed_at}" if self.processed_at
67
67
 
68
68
  at = options.delete(:at)
69
- now = Time.zone.now
69
+ now = Time.current
70
70
 
71
71
  self.queued_at = now
72
72
  self.run_at = case
@@ -61,7 +61,7 @@ module Postburner
61
61
  #
62
62
  def log_exception(exception)
63
63
  self.errata << [
64
- Time.zone.now,
64
+ Time.current,
65
65
  {
66
66
  bkid: self.bkid,
67
67
  class: exception.class,
@@ -123,7 +123,7 @@ module Postburner
123
123
  options[:level] = :error unless LOG_LEVELS.member?(options[:level])
124
124
 
125
125
  self.logs << [
126
- Time.zone.now, # time
126
+ Time.current, # time
127
127
  {
128
128
  bkid: self.bkid,
129
129
  level: options[:level], # level
@@ -99,7 +99,7 @@ module Postburner
99
99
  #
100
100
  def elapsed_ms
101
101
  return unless self.attempting_at
102
- (Time.zone.now - self.attempting_at) * 1000
102
+ (Time.current - self.attempting_at) * 1000
103
103
  end
104
104
 
105
105
  # Returns the intended execution time for the job.
@@ -3,8 +3,8 @@
3
3
  module Postburner
4
4
  # Base class for all Postburner background jobs using Single Table Inheritance (STI).
5
5
  #
6
- # Postburner::Job provides a PostgreSQL-backed job queue system built on Backburner
7
- # and Beanstalkd. Every job is stored as an ActiveRecord model, enabling database
6
+ # Postburner::Job provides a PostgreSQL-backed job queue system built on Beanstalkd.
7
+ # Every job is stored as an ActiveRecord model, enabling database
8
8
  # queries, foreign key relationships, and full audit trails.
9
9
  #
10
10
  # @abstract Subclass and implement {#perform} to define job behavior
@@ -47,8 +47,7 @@ module Postburner
47
47
  # @note Job won't run unless queued_at is set and is prior to execution time
48
48
  # @note Subclasses must implement the {#perform} method
49
49
  #
50
- # @todo Add support for ActiveJob::Arguments serialization
51
- # @todo Add `cancelled_at` field to block job execution if present
50
+ # @todo Add `cancelled_at` field to block job execution if present (See opensource/postburner#16)
52
51
  #
53
52
  # @attr_reader [Integer] id Primary key
54
53
  # @attr_reader [String] type STI type column for job subclass
@@ -79,8 +78,13 @@ module Postburner
79
78
  include Execution
80
79
  include Statistics
81
80
 
81
+ # Association to schedule execution (if job was created by scheduler)
82
+ has_one :schedule_execution
83
+ has_one :schedule, through: :schedule_execution
84
+
82
85
  before_validation :ensure_sid!
83
86
  before_destroy :delete!
87
+ before_attempt :schedule_next_execution
84
88
 
85
89
  validates :sid, presence: {strict: true}
86
90
 
@@ -286,5 +290,24 @@ module Postburner
286
290
  self.sid ||= SecureRandom.uuid
287
291
  end
288
292
 
293
+ # Before-attempt callback that creates the next schedule execution.
294
+ #
295
+ # If this job was created by a schedule, delegates to Schedule to create
296
+ # the next execution. This provides immediate pickup without waiting for
297
+ # the scheduler watchdog.
298
+ #
299
+ # Only applies to Postburner::Job-based schedules, not ActiveJob schedules.
300
+ # The scheduler watchdog remains the safety net for all schedules.
301
+ #
302
+ # @return [void]
303
+ #
304
+ # @api private
305
+ #
306
+ def schedule_next_execution
307
+ return unless schedule_execution.present?
308
+
309
+ schedule.create_next_execution!(after: schedule_execution)
310
+ end
311
+
289
312
  end
290
313
  end
@@ -2,7 +2,7 @@ module Postburner
2
2
  # Send a mailer, tracked.
3
3
  #
4
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
5
+ # Postburner::Mailer.deliver(UserMailer, :welcome).with(user_id: 1).queue! at: Time.current + 1.day
6
6
  # Postburner::Mailer.deliver(UserMailer, :welcome).with(user_id: 1).queue! delay: 5.minutes
7
7
  class Mailer < Job
8
8
  #queue 'mailers'