solid_queue 0.2.2 → 0.3.1

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +60 -7
  3. data/app/models/solid_queue/blocked_execution.rb +16 -10
  4. data/app/models/solid_queue/claimed_execution.rb +11 -5
  5. data/app/models/solid_queue/execution/dispatching.rb +2 -3
  6. data/app/models/solid_queue/execution.rb +32 -15
  7. data/app/models/solid_queue/failed_execution.rb +10 -6
  8. data/app/models/solid_queue/job/clearable.rb +3 -3
  9. data/app/models/solid_queue/job/executable.rb +3 -7
  10. data/app/models/solid_queue/job/recurrable.rb +13 -0
  11. data/app/models/solid_queue/job/schedulable.rb +1 -1
  12. data/app/models/solid_queue/job.rb +1 -1
  13. data/app/models/solid_queue/process/prunable.rb +6 -5
  14. data/app/models/solid_queue/process.rb +13 -6
  15. data/app/models/solid_queue/recurring_execution.rb +26 -0
  16. data/app/models/solid_queue/scheduled_execution.rb +3 -1
  17. data/app/models/solid_queue/semaphore.rb +1 -1
  18. data/db/migrate/20240218110712_create_recurring_executions.rb +14 -0
  19. data/lib/active_job/queue_adapters/solid_queue_adapter.rb +4 -0
  20. data/lib/generators/solid_queue/install/templates/config.yml +1 -1
  21. data/lib/puma/plugin/solid_queue.rb +1 -0
  22. data/lib/solid_queue/app_executor.rb +1 -1
  23. data/lib/solid_queue/configuration.rb +14 -5
  24. data/lib/solid_queue/dispatcher/concurrency_maintenance.rb +44 -0
  25. data/lib/solid_queue/dispatcher/recurring_schedule.rb +56 -0
  26. data/lib/solid_queue/dispatcher/recurring_task.rb +91 -0
  27. data/lib/solid_queue/dispatcher.rb +24 -39
  28. data/lib/solid_queue/engine.rb +4 -2
  29. data/lib/solid_queue/log_subscriber.rb +164 -0
  30. data/lib/solid_queue/processes/base.rb +13 -14
  31. data/lib/solid_queue/processes/callbacks.rb +19 -0
  32. data/lib/solid_queue/processes/interruptible.rb +1 -1
  33. data/lib/solid_queue/processes/poller.rb +34 -4
  34. data/lib/solid_queue/processes/registrable.rb +9 -28
  35. data/lib/solid_queue/processes/runnable.rb +33 -47
  36. data/lib/solid_queue/processes/signals.rb +1 -1
  37. data/lib/solid_queue/processes/supervised.rb +4 -0
  38. data/lib/solid_queue/supervisor.rb +25 -24
  39. data/lib/solid_queue/version.rb +1 -1
  40. data/lib/solid_queue/worker.rb +15 -16
  41. data/lib/solid_queue.rb +27 -20
  42. metadata +129 -9
@@ -5,28 +5,22 @@ module SolidQueue::Processes
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- set_callback :boot, :after, :register
9
- set_callback :boot, :after, :launch_heartbeat
8
+ after_boot :register, :launch_heartbeat
10
9
 
11
- set_callback :shutdown, :before, :stop_heartbeat
12
- set_callback :shutdown, :after, :deregister
10
+ before_shutdown :stop_heartbeat
11
+ after_shutdown :deregister
13
12
  end
14
13
 
15
- def inspect
16
- "#{kind}(pid=#{process_pid}, hostname=#{hostname}, metadata=#{metadata})"
17
- end
18
- alias to_s inspect
19
-
20
14
  private
21
15
  attr_accessor :process
22
16
 
23
17
  def register
24
18
  @process = SolidQueue::Process.register \
25
19
  kind: self.class.name.demodulize,
26
- pid: process_pid,
20
+ pid: pid,
27
21
  hostname: hostname,
28
22
  supervisor: try(:supervisor),
29
- metadata: metadata
23
+ metadata: metadata.compact
30
24
  end
31
25
 
32
26
  def deregister
@@ -38,7 +32,10 @@ module SolidQueue::Processes
38
32
  end
39
33
 
40
34
  def launch_heartbeat
41
- @heartbeat_task = Concurrent::TimerTask.new(execution_interval: SolidQueue.process_heartbeat_interval) { heartbeat }
35
+ @heartbeat_task = Concurrent::TimerTask.new(execution_interval: SolidQueue.process_heartbeat_interval) do
36
+ wrap_in_app_executor { heartbeat }
37
+ end
38
+
42
39
  @heartbeat_task.execute
43
40
  end
44
41
 
@@ -49,21 +46,5 @@ module SolidQueue::Processes
49
46
  def heartbeat
50
47
  process.heartbeat
51
48
  end
52
-
53
- def kind
54
- self.class.name.demodulize
55
- end
56
-
57
- def hostname
58
- @hostname ||= Socket.gethostname.force_encoding(Encoding::UTF_8)
59
- end
60
-
61
- def process_pid
62
- @pid ||= ::Process.pid
63
- end
64
-
65
- def metadata
66
- {}
67
- end
68
49
  end
69
50
  end
@@ -9,10 +9,11 @@ module SolidQueue::Processes
9
9
  def start
10
10
  @stopping = false
11
11
 
12
- observe_initial_delay
13
- run_callbacks(:boot) { boot }
12
+ SolidQueue.instrument(:start_process, process: self) do
13
+ run_callbacks(:boot) { boot }
14
+ end
14
15
 
15
- start_loop
16
+ run
16
17
  end
17
18
 
18
19
  def stop
@@ -20,60 +21,45 @@ module SolidQueue::Processes
20
21
  @thread&.join
21
22
  end
22
23
 
23
- private
24
- DEFAULT_MODE = :async
25
-
26
- def mode
27
- (@mode || DEFAULT_MODE).to_s.inquiry
28
- end
29
-
30
- def boot
31
- register_signal_handlers if supervised?
32
- SolidQueue.logger.info("[SolidQueue] Starting #{self}")
33
- end
24
+ private
25
+ DEFAULT_MODE = :async
34
26
 
35
- def start_loop
36
- if mode.async?
37
- @thread = Thread.new { do_start_loop }
38
- else
39
- do_start_loop
27
+ def mode
28
+ (@mode || DEFAULT_MODE).to_s.inquiry
40
29
  end
41
- end
42
30
 
43
- def do_start_loop
44
- loop do
45
- break if shutting_down?
46
-
47
- wrap_in_app_executor do
48
- run
31
+ def boot
32
+ if supervised?
33
+ register_signal_handlers
34
+ set_procline
49
35
  end
50
36
  end
51
- ensure
52
- run_callbacks(:shutdown) { shutdown }
53
- end
54
37
 
55
- def shutting_down?
56
- stopping? || supervisor_went_away? || finished?
57
- end
38
+ def shutting_down?
39
+ stopping? || supervisor_went_away? || finished?
40
+ end
58
41
 
59
- def run
60
- raise NotImplementedError
61
- end
42
+ def run
43
+ raise NotImplementedError
44
+ end
62
45
 
63
- def stopping?
64
- @stopping
65
- end
46
+ def stopping?
47
+ @stopping
48
+ end
66
49
 
67
- def finished?
68
- running_inline? && all_work_completed?
69
- end
50
+ def finished?
51
+ running_inline? && all_work_completed?
52
+ end
70
53
 
71
- def all_work_completed?
72
- false
73
- end
54
+ def all_work_completed?
55
+ false
56
+ end
74
57
 
75
- def running_inline?
76
- mode.inline?
77
- end
58
+ def set_procline
59
+ end
60
+
61
+ def running_inline?
62
+ mode.inline?
63
+ end
78
64
  end
79
65
  end
@@ -38,7 +38,7 @@ module SolidQueue::Processes
38
38
  when :QUIT
39
39
  request_immediate_termination
40
40
  else
41
- SolidQueue.logger.warn "Received unhandled signal #{signal}"
41
+ SolidQueue.instrument :unhandled_signal_error, signal: signal
42
42
  end
43
43
  end
44
44
 
@@ -14,6 +14,10 @@ module SolidQueue::Processes
14
14
  end
15
15
 
16
16
  private
17
+ def set_procline
18
+ procline "waiting"
19
+ end
20
+
17
21
  def supervisor_went_away?
18
22
  supervised? && supervisor&.pid != ::Process.ppid
19
23
  end
@@ -4,8 +4,6 @@ module SolidQueue
4
4
  class Supervisor < Processes::Base
5
5
  include Processes::Signals
6
6
 
7
- set_callback :boot, :after, :launch_process_prune
8
-
9
7
  class << self
10
8
  def start(mode: :work, load_configuration_from: nil)
11
9
  SolidQueue.supervisor = true
@@ -23,6 +21,8 @@ module SolidQueue
23
21
  def start
24
22
  run_callbacks(:boot) { boot }
25
23
 
24
+ start_forks
25
+ launch_process_prune
26
26
  supervise
27
27
  rescue Processes::GracefulTerminationRequested
28
28
  graceful_termination
@@ -42,8 +42,6 @@ module SolidQueue
42
42
  end
43
43
 
44
44
  def supervise
45
- start_forks
46
-
47
45
  loop do
48
46
  procline "supervising #{forks.keys.join(", ")}"
49
47
 
@@ -63,15 +61,15 @@ module SolidQueue
63
61
  end
64
62
  end
65
63
 
64
+ def start_forks
65
+ configured_processes.each { |configured_process| start_fork(configured_process) }
66
+ end
67
+
66
68
  def launch_process_prune
67
69
  @prune_task = Concurrent::TimerTask.new(run_now: true, execution_interval: SolidQueue.process_alive_threshold) { prune_dead_processes }
68
70
  @prune_task.execute
69
71
  end
70
72
 
71
- def start_forks
72
- configured_processes.each { |configured_process| start_fork(configured_process) }
73
- end
74
-
75
73
  def shutdown
76
74
  stop_process_prune
77
75
  restore_default_signal_handlers
@@ -79,19 +77,24 @@ module SolidQueue
79
77
  end
80
78
 
81
79
  def graceful_termination
82
- SolidQueue.logger.info("[SolidQueue] Terminating gracefully...")
83
- term_forks
80
+ SolidQueue.instrument(:graceful_termination, supervisor_pid: ::Process.pid, supervised_pids: forks.keys) do |payload|
81
+ term_forks
84
82
 
85
- wait_until(SolidQueue.shutdown_timeout, -> { all_forks_terminated? }) do
86
- reap_terminated_forks
87
- end
83
+ wait_until(SolidQueue.shutdown_timeout, -> { all_forks_terminated? }) do
84
+ reap_terminated_forks
85
+ end
88
86
 
89
- immediate_termination unless all_forks_terminated?
87
+ unless all_forks_terminated?
88
+ payload[:shutdown_timeout_exceeded] = true
89
+ immediate_termination
90
+ end
91
+ end
90
92
  end
91
93
 
92
94
  def immediate_termination
93
- SolidQueue.logger.info("[SolidQueue] Terminating immediately...")
94
- quit_forks
95
+ SolidQueue.instrument(:immediate_termination, supervisor_pid: ::Process.pid, supervised_pids: forks.keys) do
96
+ quit_forks
97
+ end
95
98
  end
96
99
 
97
100
  def term_forks
@@ -111,9 +114,7 @@ module SolidQueue
111
114
  end
112
115
 
113
116
  def prune_dead_processes
114
- wrap_in_app_executor do
115
- SolidQueue::Process.prune
116
- end
117
+ wrap_in_app_executor { SolidQueue::Process.prune }
117
118
  end
118
119
 
119
120
  def start_fork(configured_process)
@@ -147,11 +148,11 @@ module SolidQueue
147
148
  end
148
149
 
149
150
  def replace_fork(pid, status)
150
- if supervised_fork = forks.delete(pid)
151
- SolidQueue.logger.info "[SolidQueue] Restarting fork[#{status.pid}] (status: #{status.exitstatus})"
152
- start_fork(supervised_fork)
153
- else
154
- SolidQueue.logger.info "[SolidQueue] Tried to replace fork[#{pid}] (status: #{status.exitstatus}, fork[#{status.pid}]), but it had already died (status: #{status.exitstatus})"
151
+ SolidQueue.instrument(:replace_fork, supervisor_pid: ::Process.pid, pid: pid, status: status) do |payload|
152
+ if supervised_fork = forks.delete(pid)
153
+ payload[:fork] = supervised_fork
154
+ start_fork(supervised_fork)
155
+ end
155
156
  end
156
157
  end
157
158
 
@@ -1,3 +1,3 @@
1
1
  module SolidQueue
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module SolidQueue
4
4
  class Worker < Processes::Base
5
- include Processes::Runnable, Processes::Poller
5
+ include Processes::Poller
6
6
 
7
7
  attr_accessor :queues, :pool
8
8
 
@@ -14,41 +14,40 @@ module SolidQueue
14
14
  @pool = Pool.new(options[:threads], on_idle: -> { wake_up })
15
15
  end
16
16
 
17
- private
18
- def run
19
- polled_executions = poll
20
-
21
- if polled_executions.size > 0
22
- procline "performing #{polled_executions.count} jobs"
17
+ def metadata
18
+ super.merge(queues: queues.join(","), thread_pool_size: pool.size)
19
+ end
23
20
 
24
- polled_executions.each do |execution|
21
+ private
22
+ def poll
23
+ claim_executions.then do |executions|
24
+ executions.each do |execution|
25
25
  pool.post(execution)
26
26
  end
27
- else
28
- procline "waiting for jobs in #{queues.join(",")}"
29
- interruptible_sleep(polling_interval)
27
+
28
+ executions.size
30
29
  end
31
30
  end
32
31
 
33
- def poll
32
+ def claim_executions
34
33
  with_polling_volume do
35
34
  SolidQueue::ReadyExecution.claim(queues, pool.idle_threads, process.id)
36
35
  end
37
36
  end
38
37
 
39
38
  def shutdown
40
- super
41
-
42
39
  pool.shutdown
43
40
  pool.wait_for_termination(SolidQueue.shutdown_timeout)
41
+
42
+ super
44
43
  end
45
44
 
46
45
  def all_work_completed?
47
46
  SolidQueue::ReadyExecution.aggregated_count_across(queues).zero?
48
47
  end
49
48
 
50
- def metadata
51
- super.merge(queues: queues.join(","), thread_pool_size: pool.size)
49
+ def set_procline
50
+ procline "waiting for jobs in #{queues.join(",")}"
52
51
  end
53
52
  end
54
53
  end
data/lib/solid_queue.rb CHANGED
@@ -3,26 +3,23 @@
3
3
  require "solid_queue/version"
4
4
  require "solid_queue/engine"
5
5
 
6
- require "active_job/queue_adapters/solid_queue_adapter"
7
- require "active_job/concurrency_controls"
8
-
9
- require "solid_queue/app_executor"
10
- require "solid_queue/processes/supervised"
11
- require "solid_queue/processes/registrable"
12
- require "solid_queue/processes/interruptible"
13
- require "solid_queue/processes/pidfile"
14
- require "solid_queue/processes/procline"
15
- require "solid_queue/processes/poller"
16
- require "solid_queue/processes/base"
17
- require "solid_queue/processes/runnable"
18
- require "solid_queue/processes/signals"
19
- require "solid_queue/configuration"
20
- require "solid_queue/pool"
21
- require "solid_queue/worker"
22
- require "solid_queue/dispatcher"
23
- require "solid_queue/supervisor"
6
+ require "active_job"
7
+ require "active_job/queue_adapters"
8
+
9
+ require "active_support"
10
+ require "active_support/core_ext/numeric/time"
11
+
12
+ require "zeitwerk"
13
+
14
+ loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
15
+ loader.ignore("#{__dir__}/solid_queue/tasks.rb")
16
+ loader.ignore("#{__dir__}/generators")
17
+ loader.ignore("#{__dir__}/puma")
18
+ loader.setup
24
19
 
25
20
  module SolidQueue
21
+ extend self
22
+
26
23
  mattr_accessor :logger, default: ActiveSupport::Logger.new($stdout)
27
24
  mattr_accessor :app_executor, :on_thread_error, :connects_to
28
25
 
@@ -33,6 +30,8 @@ module SolidQueue
33
30
 
34
31
  mattr_accessor :shutdown_timeout, default: 5.seconds
35
32
 
33
+ mattr_accessor :enqueue_after_transaction_commit, default: false
34
+
36
35
  mattr_accessor :silence_polling, default: true
37
36
 
38
37
  mattr_accessor :supervisor_pidfile
@@ -42,11 +41,19 @@ module SolidQueue
42
41
  mattr_accessor :clear_finished_jobs_after, default: 1.day
43
42
  mattr_accessor :default_concurrency_control_period, default: 3.minutes
44
43
 
45
- def self.supervisor?
44
+ def supervisor?
46
45
  supervisor
47
46
  end
48
47
 
49
- def self.silence_polling?
48
+ def silence_polling?
50
49
  silence_polling
51
50
  end
51
+
52
+ def preserve_finished_jobs?
53
+ preserve_finished_jobs
54
+ end
55
+
56
+ def instrument(channel, **options, &block)
57
+ ActiveSupport::Notifications.instrument("#{channel}.solid_queue", **options, &block)
58
+ end
52
59
  end
metadata CHANGED
@@ -1,29 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rosa Gutierrez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-05 00:00:00.000000000 Z
11
+ date: 2024-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '7.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '7.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activejob
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '7.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '7.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: railties
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '7.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
25
53
  - !ruby/object:Gem::Version
26
54
  version: '7.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: concurrent-ruby
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.2.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: fugit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.10.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.10.1
27
83
  - !ruby/object:Gem::Dependency
28
84
  name: debug
29
85
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +122,62 @@ dependencies:
66
122
  - - ">="
67
123
  - !ruby/object:Gem::Version
68
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: mysql2
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pg
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: sqlite3
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop-rails-omakase
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
69
181
  description: Database-backed Active Job backend.
70
182
  email:
71
183
  - rosa@37signals.com
@@ -86,6 +198,7 @@ files:
86
198
  - app/models/solid_queue/job/clearable.rb
87
199
  - app/models/solid_queue/job/concurrency_controls.rb
88
200
  - app/models/solid_queue/job/executable.rb
201
+ - app/models/solid_queue/job/recurrable.rb
89
202
  - app/models/solid_queue/job/schedulable.rb
90
203
  - app/models/solid_queue/pause.rb
91
204
  - app/models/solid_queue/process.rb
@@ -94,11 +207,13 @@ files:
94
207
  - app/models/solid_queue/queue_selector.rb
95
208
  - app/models/solid_queue/ready_execution.rb
96
209
  - app/models/solid_queue/record.rb
210
+ - app/models/solid_queue/recurring_execution.rb
97
211
  - app/models/solid_queue/scheduled_execution.rb
98
212
  - app/models/solid_queue/semaphore.rb
99
213
  - config/routes.rb
100
214
  - db/migrate/20231211200639_create_solid_queue_tables.rb
101
215
  - db/migrate/20240110143450_add_missing_index_to_blocked_executions.rb
216
+ - db/migrate/20240218110712_create_recurring_executions.rb
102
217
  - lib/active_job/concurrency_controls.rb
103
218
  - lib/active_job/queue_adapters/solid_queue_adapter.rb
104
219
  - lib/generators/solid_queue/install/USAGE
@@ -109,9 +224,14 @@ files:
109
224
  - lib/solid_queue/app_executor.rb
110
225
  - lib/solid_queue/configuration.rb
111
226
  - lib/solid_queue/dispatcher.rb
227
+ - lib/solid_queue/dispatcher/concurrency_maintenance.rb
228
+ - lib/solid_queue/dispatcher/recurring_schedule.rb
229
+ - lib/solid_queue/dispatcher/recurring_task.rb
112
230
  - lib/solid_queue/engine.rb
231
+ - lib/solid_queue/log_subscriber.rb
113
232
  - lib/solid_queue/pool.rb
114
233
  - lib/solid_queue/processes/base.rb
234
+ - lib/solid_queue/processes/callbacks.rb
115
235
  - lib/solid_queue/processes/interruptible.rb
116
236
  - lib/solid_queue/processes/pidfile.rb
117
237
  - lib/solid_queue/processes/poller.rb
@@ -124,12 +244,12 @@ files:
124
244
  - lib/solid_queue/tasks.rb
125
245
  - lib/solid_queue/version.rb
126
246
  - lib/solid_queue/worker.rb
127
- homepage: https://github.com/basecamp/solid_queue
247
+ homepage: https://github.com/rails/solid_queue
128
248
  licenses:
129
249
  - MIT
130
250
  metadata:
131
- homepage_uri: https://github.com/basecamp/solid_queue
132
- source_code_uri: https://github.com/basecamp/solid_queue
251
+ homepage_uri: https://github.com/rails/solid_queue
252
+ source_code_uri: https://github.com/rails/solid_queue
133
253
  post_install_message:
134
254
  rdoc_options: []
135
255
  require_paths:
@@ -145,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
265
  - !ruby/object:Gem::Version
146
266
  version: '0'
147
267
  requirements: []
148
- rubygems_version: 3.4.10
268
+ rubygems_version: 3.5.9
149
269
  signing_key:
150
270
  specification_version: 4
151
271
  summary: Database-backed Active Job backend.