postburner 1.0.0.rc.4 → 1.0.0.rc.5

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: fc5a8c616b4bf393b03fdc5d2bef57eb03e1a9b9dc06fe592f89b3d1238c2606
4
- data.tar.gz: 40fe3028ce331e7ecbc6facb5829b845272ce66c14578cdd12b79a4495de85ce
3
+ metadata.gz: 62187fb2fd681e87e1028c52cbd6f3756b32c895c05390bffca05d51e1287ec7
4
+ data.tar.gz: 31ab083d1e9d00bfb7dc6fabbf09d7065f5062d73a6cd738835a0b76f54426b6
5
5
  SHA512:
6
- metadata.gz: 2e3095d5efd3761db840b44461f42f127269608a6070ead2e9b5751054e3875e11098d34ac9232237baa27350ec46fbf8413a80adde99feae0115bedd9b08e68
7
- data.tar.gz: 3a38ad87ba8692bae49462dbf6ac8e0013cb64209200c44201a25e5cb5d2c73ea14719753f279da4ce7da016d1af581a446bec7ad97af035f4884d645c12fefe
6
+ metadata.gz: d2e7a422e53852490b5e2ec8502f3dd69a34f17975ee808f463658f20f2ca228c5467d149987caaf7e905433b364b30c7f92142e07e7f7da3bbd7763d99c6284
7
+ data.tar.gz: aa6ce11d8f045be5b259a1869339117ddf40fca8e6d3579ced469355d2c89fbd7f19da96903154dac11a0f0efed57db840c1581ba9512c2665300d58d0453e32
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.0.0.rc.5 - 2026-06-26
4
+
5
+ ### Fixed
6
+ - `Postburner::Scheduler#ensure_future_execution!` no longer accumulates duplicate future `Postburner::ScheduleExecution` rows. The watchdog (every `scheduler_interval`, default 300s) created and enqueued one extra future execution on **every** cycle, building up dozens or hundreds of Beanstalkd delayed jobs that all eventually fire.
7
+
3
8
  ## v1.0.0.rc.4 - 2026-06-10
4
9
 
5
10
  ### Added
@@ -88,6 +88,21 @@ module Postburner
88
88
 
89
89
  validates :sid, presence: {strict: true}
90
90
 
91
+ # Jobs that have been picked up by a worker but have not yet completed or
92
+ # been removed, i.e. currently in-flight.
93
+ #
94
+ # @note A job whose worker crashed mid-run can remain in this scope even
95
+ # though nothing is executing. Beanstalkd's reserved count
96
+ # ({Postburner.stats}) is the ground truth for what is actually running.
97
+ #
98
+ # @example
99
+ # Postburner::Job.processing # all in-flight tracked jobs
100
+ # Postburner::TrackedJob.processing # in-flight tracked ActiveJobs
101
+ #
102
+ scope :processing, -> {
103
+ where.not(processing_at: nil).where(processed_at: nil, removed_at: nil)
104
+ }
105
+
91
106
  # Resolves an STI type name to a class, falling back to OrphanedJob when the
92
107
  # original class no longer exists. This tolerates rows whose `type` column
93
108
  # references a deleted or renamed job class, preventing
@@ -484,7 +484,32 @@ module Postburner
484
484
  return true
485
485
  end
486
486
 
487
- # Delegate to Schedule - it knows whether a future execution is needed
487
+ # GUARD: Only create a new future execution if none exists yet (relative to now).
488
+ #
489
+ # This guard intentionally uses Time.current, while the inner guard inside
490
+ # create_next_execution! (schedule.rb:199-200) uses after.run_at. They answer
491
+ # DIFFERENT questions:
492
+ #
493
+ # Watchdog (here): "Does ANY execution exist in the future?"
494
+ # before_attempt callback: "Does an execution exist AFTER the one now running?"
495
+ #
496
+ # The before_attempt callback (job.rb:380) passes `after: current_execution` so
497
+ # create_next_execution!'s check_time ≈ Time.current — it correctly fires when
498
+ # the watchdog has already queued a successor. But when this method calls
499
+ # create_next_execution!(after: last_execution), check_time becomes
500
+ # last_execution.run_at — the highest run_at in the table by definition — so
501
+ # the inner guard can never find an execution beyond it and would always create
502
+ # another, accumulating one extra future execution per watchdog cycle.
503
+ #
504
+ # Note: > (not >=) is intentional. A just-fired execution at run_at == Time.current
505
+ # must NOT block creation of its successor.
506
+ #
507
+ # The inner guard in create_next_execution! is STILL REQUIRED for the
508
+ # before_attempt callback path and must NOT be removed even though it is
509
+ # effectively bypassed on the watchdog path now that this outer guard fires first.
510
+ return false if schedule.executions.where('run_at > ?', Time.current).exists?
511
+
512
+ # Delegate to Schedule - it knows how to calculate the next run time
488
513
  execution = schedule.create_next_execution!(after: last_execution)
489
514
 
490
515
  if execution
@@ -1,3 +1,3 @@
1
1
  module Postburner
2
- VERSION = '1.0.0.rc.4'
2
+ VERSION = '1.0.0.rc.5'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postburner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc.4
4
+ version: 1.0.0.rc.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Smith