que 0.14.3 → 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
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: []