solid_queue 1.4.0 → 1.6.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.
@@ -13,6 +13,8 @@ module SolidQueue
13
13
  configuration = Configuration.new(**options)
14
14
 
15
15
  if configuration.valid?
16
+ configuration.warnings.full_messages.each { |warning| SolidQueue.logger.warn(warning) }
17
+
16
18
  klass = configuration.mode.fork? ? ForkSupervisor : AsyncSupervisor
17
19
  klass.new(configuration).tap(&:start)
18
20
  else
@@ -4,8 +4,19 @@ namespace :solid_queue do
4
4
  Rails::Command.invoke :generate, [ "solid_queue:install" ]
5
5
  end
6
6
 
7
+ desc "Copy any new Solid Queue migrations to the application"
8
+ task :update do
9
+ Rails::Command.invoke :generate, [ "solid_queue:update" ]
10
+ end
11
+
7
12
  desc "start solid_queue supervisor to dispatch and process jobs"
8
13
  task start: :environment do
9
14
  SolidQueue::Supervisor.start
10
15
  end
16
+
17
+ desc "validate the Solid Queue configuration for the current Rails env without starting any process"
18
+ task check: :environment do
19
+ configuration = SolidQueue::Configuration.new
20
+ exit 1 unless configuration.check
21
+ end
11
22
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidQueue
4
+ class ThreadPool < Pool
5
+ delegate :shutdown, :shutdown?, :wait_for_termination, to: :executor
6
+
7
+ private
8
+ DEFAULT_OPTIONS = {
9
+ min_threads: 0,
10
+ idletime: 60,
11
+ fallback_policy: :abort
12
+ }
13
+
14
+ def schedule(execution)
15
+ Concurrent::Promises.future_on(executor, execution) do |thread_execution|
16
+ perform_execution(thread_execution)
17
+ end.on_rejection! do |error|
18
+ # Backstop for errors raised outside perform_execution's own rescue,
19
+ # such as when restoring capacity or waking up the worker
20
+ handle_thread_error(error)
21
+ end
22
+ end
23
+
24
+ def executor
25
+ @executor ||= Concurrent::ThreadPoolExecutor.new DEFAULT_OPTIONS.merge(max_threads: size, max_queue: size)
26
+ end
27
+ end
28
+ end
@@ -20,9 +20,8 @@ module SolidQueue
20
20
  end
21
21
  end
22
22
 
23
- private
24
- def monotonic_time_now
25
- ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
26
- end
23
+ def monotonic_time_now
24
+ ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
25
+ end
27
26
  end
28
27
  end
@@ -1,3 +1,7 @@
1
1
  module SolidQueue
2
- VERSION = "1.4.0"
2
+ VERSION = "1.6.0"
3
+
4
+ def self.next_major_version
5
+ Gem::Version.new(VERSION).segments.first + 1
6
+ end
3
7
  end
@@ -11,18 +11,24 @@ module SolidQueue
11
11
  attr_reader :queues, :pool
12
12
 
13
13
  def initialize(**options)
14
+ execution_pool_type = options.key?(:fibers) ? :fiber : :thread
15
+
14
16
  options = options.dup.with_defaults(SolidQueue::Configuration::WORKER_DEFAULTS)
17
+ execution_pool_size = execution_pool_type == :fiber ? options[:fibers] : options[:threads]
15
18
 
16
19
  # Ensure that the queues array is deep frozen to prevent accidental modification
17
20
  @queues = Array(options[:queues]).map(&:freeze).freeze
18
21
 
19
- @pool = Pool.new(options[:threads], on_idle: -> { wake_up })
22
+ @pool = Pool.build \
23
+ type: execution_pool_type,
24
+ size: execution_pool_size,
25
+ on_idle: -> { wake_up }
20
26
 
21
27
  super(**options)
22
28
  end
23
29
 
24
30
  def metadata
25
- super.merge(queues: queues.join(","), thread_pool_size: pool.size)
31
+ super.merge(queues: queues.join(","), pool_type: pool.type, pool_size: pool.size)
26
32
  end
27
33
 
28
34
  private
@@ -38,7 +44,7 @@ module SolidQueue
38
44
 
39
45
  def claim_executions
40
46
  with_polling_volume do
41
- SolidQueue::ReadyExecution.claim(queues, pool.idle_threads, process_id)
47
+ SolidQueue::ReadyExecution.claim(queues, pool.available_capacity, process_id)
42
48
  end
43
49
  end
44
50
 
data/lib/solid_queue.rb CHANGED
@@ -29,6 +29,7 @@ module SolidQueue
29
29
 
30
30
  mattr_accessor :process_heartbeat_interval, default: 60.seconds
31
31
  mattr_accessor :process_alive_threshold, default: 5.minutes
32
+ mattr_accessor :fork_boot_timeout, default: 5.minutes
32
33
 
33
34
  mattr_accessor :shutdown_timeout, default: 5.seconds
34
35
 
@@ -41,6 +42,15 @@ module SolidQueue
41
42
  mattr_accessor :clear_finished_jobs_after, default: 1.day
42
43
  mattr_accessor :default_concurrency_control_period, default: 3.minutes
43
44
 
45
+ mattr_reader :time_zone
46
+
47
+ def time_zone=(zone)
48
+ @@time_zone = if zone
49
+ resolved = zone.respond_to?(:tzinfo) ? zone : ActiveSupport::TimeZone[zone]
50
+ resolved&.tzinfo&.name || zone.to_s
51
+ end
52
+ end
53
+
44
54
  delegate :on_start, :on_stop, :on_exit, to: Supervisor
45
55
 
46
56
  def schedule_recurring_task(key, **options)
@@ -77,6 +87,10 @@ module SolidQueue
77
87
  preserve_finished_jobs
78
88
  end
79
89
 
90
+ def deprecator
91
+ @deprecator ||= ActiveSupport::Deprecation.new(next_major_version, "SolidQueue")
92
+ end
93
+
80
94
  def instrument(channel, **options, &block)
81
95
  ActiveSupport::Notifications.instrument("#{channel}.solid_queue", **options, &block)
82
96
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rosa Gutierrez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-20 00:00:00.000000000 Z
11
+ date: 2026-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.9'
125
+ - !ruby/object:Gem::Dependency
126
+ name: async
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '2.24'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '2.24'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: minitest
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -294,6 +308,7 @@ files:
294
308
  - app/models/solid_queue/queue_selector.rb
295
309
  - app/models/solid_queue/ready_execution.rb
296
310
  - app/models/solid_queue/record.rb
311
+ - app/models/solid_queue/record/distinct_values.rb
297
312
  - app/models/solid_queue/recurring_execution.rb
298
313
  - app/models/solid_queue/recurring_task.rb
299
314
  - app/models/solid_queue/recurring_task/arguments.rb
@@ -308,6 +323,7 @@ files:
308
323
  - lib/generators/solid_queue/install/templates/config/queue.yml
309
324
  - lib/generators/solid_queue/install/templates/config/recurring.yml
310
325
  - lib/generators/solid_queue/install/templates/db/queue_schema.rb
326
+ - lib/generators/solid_queue/update/update_generator.rb
311
327
  - lib/puma/plugin/solid_queue.rb
312
328
  - lib/solid_queue.rb
313
329
  - lib/solid_queue/app_executor.rb
@@ -317,6 +333,7 @@ files:
317
333
  - lib/solid_queue/dispatcher.rb
318
334
  - lib/solid_queue/dispatcher/concurrency_maintenance.rb
319
335
  - lib/solid_queue/engine.rb
336
+ - lib/solid_queue/fiber_pool.rb
320
337
  - lib/solid_queue/fork_supervisor.rb
321
338
  - lib/solid_queue/lifecycle_hooks.rb
322
339
  - lib/solid_queue/log_subscriber.rb
@@ -341,6 +358,7 @@ files:
341
358
  - lib/solid_queue/supervisor/pidfiled.rb
342
359
  - lib/solid_queue/supervisor/signals.rb
343
360
  - lib/solid_queue/tasks.rb
361
+ - lib/solid_queue/thread_pool.rb
344
362
  - lib/solid_queue/timer.rb
345
363
  - lib/solid_queue/version.rb
346
364
  - lib/solid_queue/worker.rb
@@ -360,7 +378,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
360
378
  requirements:
361
379
  - - ">="
362
380
  - !ruby/object:Gem::Version
363
- version: '3.1'
381
+ version: '3.2'
364
382
  required_rubygems_version: !ruby/object:Gem::Requirement
365
383
  requirements:
366
384
  - - ">="