que 0.14.3 → 1.0.0.beta

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 (102) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +108 -14
  4. data/LICENSE.txt +1 -1
  5. data/README.md +49 -45
  6. data/bin/command_line_interface.rb +239 -0
  7. data/bin/que +8 -82
  8. data/docs/README.md +2 -0
  9. data/docs/active_job.md +6 -0
  10. data/docs/advanced_setup.md +7 -64
  11. data/docs/command_line_interface.md +45 -0
  12. data/docs/error_handling.md +65 -18
  13. data/docs/inspecting_the_queue.md +30 -80
  14. data/docs/job_helper_methods.md +27 -0
  15. data/docs/logging.md +3 -22
  16. data/docs/managing_workers.md +6 -61
  17. data/docs/middleware.md +15 -0
  18. data/docs/migrating.md +4 -7
  19. data/docs/multiple_queues.md +8 -4
  20. data/docs/shutting_down_safely.md +1 -1
  21. data/docs/using_plain_connections.md +39 -15
  22. data/docs/using_sequel.md +5 -3
  23. data/docs/writing_reliable_jobs.md +15 -24
  24. data/lib/que.rb +98 -182
  25. data/lib/que/active_job/extensions.rb +97 -0
  26. data/lib/que/active_record/connection.rb +51 -0
  27. data/lib/que/active_record/model.rb +48 -0
  28. data/lib/que/connection.rb +179 -0
  29. data/lib/que/connection_pool.rb +78 -0
  30. data/lib/que/job.rb +107 -156
  31. data/lib/que/job_cache.rb +240 -0
  32. data/lib/que/job_methods.rb +168 -0
  33. data/lib/que/listener.rb +176 -0
  34. data/lib/que/locker.rb +466 -0
  35. data/lib/que/metajob.rb +47 -0
  36. data/lib/que/migrations.rb +24 -17
  37. data/lib/que/migrations/4/down.sql +48 -0
  38. data/lib/que/migrations/4/up.sql +265 -0
  39. data/lib/que/poller.rb +267 -0
  40. data/lib/que/rails/railtie.rb +14 -0
  41. data/lib/que/result_queue.rb +35 -0
  42. data/lib/que/sequel/model.rb +51 -0
  43. data/lib/que/utils/assertions.rb +62 -0
  44. data/lib/que/utils/constantization.rb +19 -0
  45. data/lib/que/utils/error_notification.rb +68 -0
  46. data/lib/que/utils/freeze.rb +20 -0
  47. data/lib/que/utils/introspection.rb +50 -0
  48. data/lib/que/utils/json_serialization.rb +21 -0
  49. data/lib/que/utils/logging.rb +78 -0
  50. data/lib/que/utils/middleware.rb +33 -0
  51. data/lib/que/utils/queue_management.rb +18 -0
  52. data/lib/que/utils/transactions.rb +34 -0
  53. data/lib/que/version.rb +1 -1
  54. data/lib/que/worker.rb +128 -167
  55. data/que.gemspec +13 -2
  56. metadata +37 -80
  57. data/.rspec +0 -2
  58. data/.travis.yml +0 -64
  59. data/Gemfile +0 -24
  60. data/docs/customizing_que.md +0 -200
  61. data/lib/generators/que/install_generator.rb +0 -24
  62. data/lib/generators/que/templates/add_que.rb +0 -13
  63. data/lib/que/adapters/active_record.rb +0 -40
  64. data/lib/que/adapters/base.rb +0 -133
  65. data/lib/que/adapters/connection_pool.rb +0 -16
  66. data/lib/que/adapters/pg.rb +0 -21
  67. data/lib/que/adapters/pond.rb +0 -16
  68. data/lib/que/adapters/sequel.rb +0 -20
  69. data/lib/que/railtie.rb +0 -16
  70. data/lib/que/rake_tasks.rb +0 -59
  71. data/lib/que/sql.rb +0 -170
  72. data/spec/adapters/active_record_spec.rb +0 -175
  73. data/spec/adapters/connection_pool_spec.rb +0 -22
  74. data/spec/adapters/pg_spec.rb +0 -41
  75. data/spec/adapters/pond_spec.rb +0 -22
  76. data/spec/adapters/sequel_spec.rb +0 -57
  77. data/spec/gemfiles/Gemfile.current +0 -19
  78. data/spec/gemfiles/Gemfile.old +0 -19
  79. data/spec/gemfiles/Gemfile.older +0 -19
  80. data/spec/gemfiles/Gemfile.oldest +0 -19
  81. data/spec/spec_helper.rb +0 -129
  82. data/spec/support/helpers.rb +0 -25
  83. data/spec/support/jobs.rb +0 -35
  84. data/spec/support/shared_examples/adapter.rb +0 -42
  85. data/spec/support/shared_examples/multi_threaded_adapter.rb +0 -46
  86. data/spec/unit/configuration_spec.rb +0 -31
  87. data/spec/unit/connection_spec.rb +0 -14
  88. data/spec/unit/customization_spec.rb +0 -251
  89. data/spec/unit/enqueue_spec.rb +0 -245
  90. data/spec/unit/helper_spec.rb +0 -12
  91. data/spec/unit/logging_spec.rb +0 -101
  92. data/spec/unit/migrations_spec.rb +0 -84
  93. data/spec/unit/pool_spec.rb +0 -365
  94. data/spec/unit/run_spec.rb +0 -14
  95. data/spec/unit/states_spec.rb +0 -50
  96. data/spec/unit/stats_spec.rb +0 -46
  97. data/spec/unit/transaction_spec.rb +0 -36
  98. data/spec/unit/work_spec.rb +0 -596
  99. data/spec/unit/worker_spec.rb +0 -167
  100. data/tasks/benchmark.rb +0 -3
  101. data/tasks/rspec.rb +0 -14
  102. data/tasks/safe_shutdown.rb +0 -67
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Tools for managing the contents/state of the queue.
4
+
5
+ module Que
6
+ module Utils
7
+ module QueueManagement
8
+ def clear!
9
+ execute "DELETE FROM que_jobs"
10
+ end
11
+
12
+ # Very old migrations may use Que.create! and Que.drop!, which just
13
+ # created and dropped the initial version of the jobs table.
14
+ def create!; migrate!(version: 1); end
15
+ def drop!; migrate!(version: 0); end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A helper method to manage transactions, used mainly by the migration system.
4
+ # It's available for general use, but if you're using an ORM that provides its
5
+ # own transaction helper, be sure to use that instead, or the two may interfere
6
+ # with one another.
7
+
8
+ module Que
9
+ module Utils
10
+ module Transactions
11
+ def transaction
12
+ pool.checkout do
13
+ if pool.in_transaction?
14
+ yield
15
+ else
16
+ begin
17
+ execute "BEGIN"
18
+ yield
19
+ rescue => error
20
+ raise
21
+ ensure
22
+ # Handle a raised error or a killed thread.
23
+ if error || Thread.current.status == 'aborting'
24
+ execute "ROLLBACK"
25
+ else
26
+ execute "COMMIT"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Que
4
- Version = '0.14.3'
4
+ VERSION = '1.0.0.beta'
5
5
  end
@@ -1,196 +1,157 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'monitor'
3
+ # Workers wrap threads which continuously pull job pks from JobCache objects,
4
+ # fetch and work those jobs, and export relevant data to ResultQueues.
4
5
 
5
6
  module Que
6
7
  class Worker
7
- # Each worker has a thread that does the actual work of running jobs.
8
- # Since both the worker's thread and whatever thread is managing the
9
- # worker are capable of affecting the worker's state, we need to
10
- # synchronize access to it.
11
- include MonitorMixin
12
-
13
- attr_reader :thread, :state, :queue
14
-
15
- def initialize(queue = '')
16
- super() # For MonitorMixin.
17
- @queue = queue
18
- @state = :working
19
- @thread = Thread.new { work_loop }
20
- @thread.abort_on_exception = true
21
- end
22
-
23
- def alive?
24
- !!@thread.status
25
- end
26
-
27
- def sleeping?
28
- synchronize { _sleeping? }
29
- end
30
-
31
- def working?
32
- synchronize { @state == :working }
33
- end
34
-
35
- def wake!
36
- synchronize do
37
- if sleeping?
38
- # Have to set the state here so that another thread checking
39
- # immediately after this won't see the worker as asleep.
40
- @state = :working
41
- @thread.wakeup
42
- true
43
- end
8
+ attr_reader :thread, :priority
9
+
10
+ SQL[:check_job] =
11
+ %{
12
+ SELECT 1 AS one
13
+ FROM public.que_jobs
14
+ WHERE id = $1::bigint
15
+ }
16
+
17
+ def initialize(
18
+ job_cache:,
19
+ result_queue:,
20
+ priority: nil,
21
+ start_callback: nil
22
+ )
23
+
24
+ @priority = Que.assert([NilClass, Integer], priority)
25
+ @job_cache = Que.assert(JobCache, job_cache)
26
+ @result_queue = Que.assert(ResultQueue, result_queue)
27
+
28
+ Que.internal_log(:worker_instantiate, self) do
29
+ {
30
+ priority: priority,
31
+ job_cache: job_cache.object_id,
32
+ result_queue: result_queue.object_id,
33
+ }
44
34
  end
45
- end
46
35
 
47
- # This needs to be called when trapping a signal, so it can't lock the monitor.
48
- def stop
49
- @stop = true
50
- @thread.wakeup if _sleeping?
36
+ @thread =
37
+ Thread.new do
38
+ # An error causing this thread to exit is a bug in Que, which we want
39
+ # to know about ASAP, so propagate the error if it happens.
40
+ Thread.current.abort_on_exception = true
41
+ start_callback.call(self) if start_callback.respond_to?(:call)
42
+ work_loop
43
+ end
51
44
  end
52
45
 
53
46
  def wait_until_stopped
54
- wait while alive?
47
+ @thread.join
55
48
  end
56
49
 
57
50
  private
58
51
 
59
- # Sleep very briefly while waiting for a thread to get somewhere.
60
- def wait
61
- sleep 0.0001
62
- end
63
-
64
- def _sleeping?
65
- if @state == :sleeping
66
- # There's a very small period of time between when the Worker marks
67
- # itself as sleeping and when it actually goes to sleep. Only report
68
- # true when we're certain the thread is sleeping.
69
- wait until @thread.status == 'sleep'
70
- true
71
- end
72
- end
73
-
74
52
  def work_loop
75
- loop do
76
- cycle = nil
77
-
78
- if Que.mode == :async
79
- time = Time.now
80
- result = Job.work(queue)
81
-
82
- case result[:event]
83
- when :job_unavailable
84
- cycle = false
85
- result[:level] = :debug
86
- when :job_race_condition
87
- cycle = true
88
- result[:level] = :debug
89
- when :job_worked
90
- cycle = true
91
- result[:elapsed] = (Time.now - time).round(5)
92
- when :job_errored
93
- # For PG::Errors, assume we had a problem reaching the database, and
94
- # don't hit it again right away.
95
- cycle = !result[:error].is_a?(PG::Error)
96
- result[:error] = {:class => result[:error].class.to_s, :message => result[:error].message}
97
- else
98
- raise "Unknown Event: #{result[:event].inspect}"
99
- end
100
-
101
- Que.log(result)
53
+ # Blocks until a job of the appropriate priority is available. If the
54
+ # queue is shutting down this will return nil, which breaks the loop and
55
+ # lets the thread finish.
56
+ while metajob = fetch_next_metajob
57
+ id = metajob.id
58
+
59
+ Que.internal_log(:worker_received_job, self) { {id: id} }
60
+
61
+ if Que.execute(:check_job, [id]).first
62
+ Que.recursively_freeze(metajob.job)
63
+ Que.internal_log(:worker_fetched_job, self) { {id: id} }
64
+
65
+ work_job(metajob)
66
+ else
67
+ # The job was locked but doesn't exist anymore, due to a race
68
+ # condition that exists because advisory locks don't obey MVCC. Not
69
+ # necessarily a problem, but if it happens a lot it may be meaningful.
70
+ Que.internal_log(:worker_job_lock_race_condition, self) { {id: id} }
102
71
  end
103
72
 
104
- synchronize { @state = :sleeping unless cycle || @stop }
105
- sleep if @state == :sleeping
106
- break if @stop
107
- end
108
- ensure
109
- @state = :stopped
110
- end
111
-
112
- # Setting Que.wake_interval = nil should ensure that the wrangler thread
113
- # doesn't wake up a worker again, even if it's currently sleeping for a
114
- # set period. So, we double-check that @wake_interval is set before waking
115
- # a worker, and make sure to wake up the wrangler when @wake_interval is
116
- # changed in Que.wake_interval= below.
117
- @wake_interval = 5
73
+ Que.internal_log(:worker_pushing_finished_job, self) { {id: id} }
118
74
 
119
- # Four workers is a sensible default for most use cases.
120
- @worker_count = 4
121
-
122
- class << self
123
- attr_reader :mode, :wake_interval, :worker_count
124
- attr_accessor :queue_name
125
-
126
- # In order to work in a forking webserver, we need to be able to accept
127
- # worker_count and wake_interval settings without actually instantiating
128
- # the relevant threads until the mode is actually set to :async in a
129
- # post-fork hook (since forking will kill any running background threads).
130
-
131
- def mode=(mode)
132
- Que.log :event => 'mode_change', :value => mode.to_s
133
- @mode = mode
134
-
135
- if mode == :async
136
- set_up_workers
137
- wrangler
138
- end
139
- end
140
-
141
- def worker_count=(count)
142
- Que.log :event => 'worker_count_change', :value => count.to_s
143
- @worker_count = count
144
- set_up_workers if mode == :async
145
- end
146
-
147
- def workers
148
- @workers ||= []
149
- end
150
-
151
- def wake_interval=(interval)
152
- @wake_interval = interval
153
- begin
154
- wrangler.wakeup if mode == :async
155
- rescue ThreadError # killed thread for some reason.
156
- v = wrangler.value # Reraise the error that killed the thread.
157
- # if that didn't raise an error, something else is wrong, so raise
158
- # whatever this is:
159
- raise "Dead thread!: #{v.inspect}"
160
- end
75
+ @result_queue.push(
76
+ metajob: metajob,
77
+ message_type: :job_finished,
78
+ )
161
79
  end
80
+ end
162
81
 
163
- def wake!
164
- workers.find(&:wake!)
165
- end
82
+ def fetch_next_metajob
83
+ @job_cache.shift(*priority)
84
+ end
166
85
 
167
- def wake_all!
168
- workers.each(&:wake!)
86
+ def work_job(metajob)
87
+ job = metajob.job
88
+ start = Time.now
89
+ klass = Que.constantize(job.fetch(:job_class))
90
+ instance = klass.new(job)
91
+
92
+ Que.run_middleware(instance) { instance.tap(&:_run) }
93
+
94
+ log_message = {
95
+ level: :debug,
96
+ job_id: metajob.id,
97
+ elapsed: (Time.now - start),
98
+ }
99
+
100
+ if error = instance.que_error
101
+ log_message[:event] = :job_errored
102
+ log_message[:error] = "#{error.class}: #{error.message}".slice(0, 500)
103
+ else
104
+ log_message[:event] = :job_worked
169
105
  end
170
106
 
171
- private
172
-
173
- def set_up_workers
174
- if worker_count > workers.count
175
- workers.push(*(worker_count - workers.count).times.map{new(queue_name || '')})
176
- elsif worker_count < workers.count
177
- workers.pop(workers.count - worker_count).each(&:stop).each(&:wait_until_stopped)
107
+ Que.log(log_message)
108
+
109
+ instance
110
+ rescue => error
111
+ Que.log(
112
+ level: :debug,
113
+ event: :job_errored,
114
+ job_id: metajob.id,
115
+ error: {
116
+ class: error.class.to_s,
117
+ message: error.message,
118
+ },
119
+ )
120
+
121
+ Que.notify_error(error)
122
+
123
+ begin
124
+ # If the Job class couldn't be resolved, use the default retry
125
+ # backoff logic in Que::Job.
126
+ job_class = (klass && klass <= Job) ? klass : Job
127
+
128
+ error_count = job.fetch(:error_count) + 1
129
+
130
+ max_retry_count = job_class.resolve_que_setting(:maximum_retry_count)
131
+
132
+ if max_retry_count && error_count > max_retry_count
133
+ Que.execute :expire_job, [job.fetch(:id)]
134
+ else
135
+ delay =
136
+ job_class.
137
+ resolve_que_setting(
138
+ :retry_interval,
139
+ error_count,
140
+ )
141
+
142
+ Que.execute :set_error, [
143
+ delay,
144
+ "#{error.class}: #{error.message}".slice(0, 500),
145
+ error.backtrace.join("\n").slice(0, 10000),
146
+ job.fetch(:id),
147
+ ]
178
148
  end
149
+ rescue
150
+ # If we can't reach the database for some reason, too bad, but
151
+ # don't let it crash the work loop.
179
152
  end
180
153
 
181
- def wrangler
182
- @wrangler ||= Thread.new do
183
- loop do
184
- if @wake_interval
185
- sleep(@wake_interval)
186
- else
187
- sleep
188
- end
189
-
190
- wake! if @wake_interval && mode == :async
191
- end
192
- end
193
- end
154
+ error
194
155
  end
195
156
  end
196
157
  end
@@ -5,7 +5,7 @@ require 'que/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'que'
8
- spec.version = Que::Version
8
+ spec.version = Que::VERSION
9
9
  spec.authors = ["Chris Hanks"]
10
10
  spec.email = ['christopher.m.hanks@gmail.com']
11
11
  spec.description = %q{A job queue that uses PostgreSQL's advisory locks for speed and reliability.}
@@ -13,7 +13,18 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'https://github.com/chanks/que'
14
14
  spec.license = 'MIT'
15
15
 
16
- spec.files = `git ls-files`.split($/)
16
+ files_to_exclude = [
17
+ /\A\.circleci/,
18
+ /\AGemfile/,
19
+ /\Aspec/,
20
+ /\Atasks/,
21
+ /spec\.rb\z/,
22
+ ]
23
+
24
+ spec.files = `git ls-files`.split($/).reject do |file|
25
+ files_to_exclude.any? { |r| r === file }
26
+ end
27
+
17
28
  spec.executables = ['que']
18
29
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
30
  spec.require_paths = ['lib']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: que
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.3
4
+ version: 1.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Hanks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-02 00:00:00.000000000 Z
11
+ date: 2017-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -33,37 +33,40 @@ extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
35
  - ".gitignore"
36
- - ".rspec"
37
- - ".travis.yml"
38
36
  - CHANGELOG.md
39
- - Gemfile
40
37
  - LICENSE.txt
41
38
  - README.md
42
39
  - Rakefile
40
+ - bin/command_line_interface.rb
43
41
  - bin/que
44
42
  - docs/README.md
43
+ - docs/active_job.md
45
44
  - docs/advanced_setup.md
46
- - docs/customizing_que.md
45
+ - docs/command_line_interface.md
47
46
  - docs/error_handling.md
48
47
  - docs/inspecting_the_queue.md
48
+ - docs/job_helper_methods.md
49
49
  - docs/logging.md
50
50
  - docs/managing_workers.md
51
+ - docs/middleware.md
51
52
  - docs/migrating.md
52
53
  - docs/multiple_queues.md
53
54
  - docs/shutting_down_safely.md
54
55
  - docs/using_plain_connections.md
55
56
  - docs/using_sequel.md
56
57
  - docs/writing_reliable_jobs.md
57
- - lib/generators/que/install_generator.rb
58
- - lib/generators/que/templates/add_que.rb
59
58
  - lib/que.rb
60
- - lib/que/adapters/active_record.rb
61
- - lib/que/adapters/base.rb
62
- - lib/que/adapters/connection_pool.rb
63
- - lib/que/adapters/pg.rb
64
- - lib/que/adapters/pond.rb
65
- - lib/que/adapters/sequel.rb
59
+ - lib/que/active_job/extensions.rb
60
+ - lib/que/active_record/connection.rb
61
+ - lib/que/active_record/model.rb
62
+ - lib/que/connection.rb
63
+ - lib/que/connection_pool.rb
66
64
  - lib/que/job.rb
65
+ - lib/que/job_cache.rb
66
+ - lib/que/job_methods.rb
67
+ - lib/que/listener.rb
68
+ - lib/que/locker.rb
69
+ - lib/que/metajob.rb
67
70
  - lib/que/migrations.rb
68
71
  - lib/que/migrations/1/down.sql
69
72
  - lib/que/migrations/1/up.sql
@@ -71,43 +74,25 @@ files:
71
74
  - lib/que/migrations/2/up.sql
72
75
  - lib/que/migrations/3/down.sql
73
76
  - lib/que/migrations/3/up.sql
74
- - lib/que/railtie.rb
75
- - lib/que/rake_tasks.rb
76
- - lib/que/sql.rb
77
+ - lib/que/migrations/4/down.sql
78
+ - lib/que/migrations/4/up.sql
79
+ - lib/que/poller.rb
80
+ - lib/que/rails/railtie.rb
81
+ - lib/que/result_queue.rb
82
+ - lib/que/sequel/model.rb
83
+ - lib/que/utils/assertions.rb
84
+ - lib/que/utils/constantization.rb
85
+ - lib/que/utils/error_notification.rb
86
+ - lib/que/utils/freeze.rb
87
+ - lib/que/utils/introspection.rb
88
+ - lib/que/utils/json_serialization.rb
89
+ - lib/que/utils/logging.rb
90
+ - lib/que/utils/middleware.rb
91
+ - lib/que/utils/queue_management.rb
92
+ - lib/que/utils/transactions.rb
77
93
  - lib/que/version.rb
78
94
  - lib/que/worker.rb
79
95
  - que.gemspec
80
- - spec/adapters/active_record_spec.rb
81
- - spec/adapters/connection_pool_spec.rb
82
- - spec/adapters/pg_spec.rb
83
- - spec/adapters/pond_spec.rb
84
- - spec/adapters/sequel_spec.rb
85
- - spec/gemfiles/Gemfile.current
86
- - spec/gemfiles/Gemfile.old
87
- - spec/gemfiles/Gemfile.older
88
- - spec/gemfiles/Gemfile.oldest
89
- - spec/spec_helper.rb
90
- - spec/support/helpers.rb
91
- - spec/support/jobs.rb
92
- - spec/support/shared_examples/adapter.rb
93
- - spec/support/shared_examples/multi_threaded_adapter.rb
94
- - spec/unit/configuration_spec.rb
95
- - spec/unit/connection_spec.rb
96
- - spec/unit/customization_spec.rb
97
- - spec/unit/enqueue_spec.rb
98
- - spec/unit/helper_spec.rb
99
- - spec/unit/logging_spec.rb
100
- - spec/unit/migrations_spec.rb
101
- - spec/unit/pool_spec.rb
102
- - spec/unit/run_spec.rb
103
- - spec/unit/states_spec.rb
104
- - spec/unit/stats_spec.rb
105
- - spec/unit/transaction_spec.rb
106
- - spec/unit/work_spec.rb
107
- - spec/unit/worker_spec.rb
108
- - tasks/benchmark.rb
109
- - tasks/rspec.rb
110
- - tasks/safe_shutdown.rb
111
96
  homepage: https://github.com/chanks/que
112
97
  licenses:
113
98
  - MIT
@@ -123,41 +108,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
108
  version: '0'
124
109
  required_rubygems_version: !ruby/object:Gem::Requirement
125
110
  requirements:
126
- - - ">="
111
+ - - ">"
127
112
  - !ruby/object:Gem::Version
128
- version: '0'
113
+ version: 1.3.1
129
114
  requirements: []
130
115
  rubyforge_project:
131
- rubygems_version: 2.7.3
116
+ rubygems_version: 2.6.14
132
117
  signing_key:
133
118
  specification_version: 4
134
119
  summary: A PostgreSQL-based Job Queue
135
- test_files:
136
- - spec/adapters/active_record_spec.rb
137
- - spec/adapters/connection_pool_spec.rb
138
- - spec/adapters/pg_spec.rb
139
- - spec/adapters/pond_spec.rb
140
- - spec/adapters/sequel_spec.rb
141
- - spec/gemfiles/Gemfile.current
142
- - spec/gemfiles/Gemfile.old
143
- - spec/gemfiles/Gemfile.older
144
- - spec/gemfiles/Gemfile.oldest
145
- - spec/spec_helper.rb
146
- - spec/support/helpers.rb
147
- - spec/support/jobs.rb
148
- - spec/support/shared_examples/adapter.rb
149
- - spec/support/shared_examples/multi_threaded_adapter.rb
150
- - spec/unit/configuration_spec.rb
151
- - spec/unit/connection_spec.rb
152
- - spec/unit/customization_spec.rb
153
- - spec/unit/enqueue_spec.rb
154
- - spec/unit/helper_spec.rb
155
- - spec/unit/logging_spec.rb
156
- - spec/unit/migrations_spec.rb
157
- - spec/unit/pool_spec.rb
158
- - spec/unit/run_spec.rb
159
- - spec/unit/states_spec.rb
160
- - spec/unit/stats_spec.rb
161
- - spec/unit/transaction_spec.rb
162
- - spec/unit/work_spec.rb
163
- - spec/unit/worker_spec.rb
120
+ test_files: []