reqless 0.0.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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +8 -0
  3. data/README.md +648 -0
  4. data/Rakefile +117 -0
  5. data/bin/docker-build-and-test +22 -0
  6. data/exe/reqless-web +11 -0
  7. data/lib/reqless/config.rb +31 -0
  8. data/lib/reqless/failure_formatter.rb +43 -0
  9. data/lib/reqless/job.rb +496 -0
  10. data/lib/reqless/job_reservers/ordered.rb +29 -0
  11. data/lib/reqless/job_reservers/round_robin.rb +46 -0
  12. data/lib/reqless/job_reservers/shuffled_round_robin.rb +21 -0
  13. data/lib/reqless/lua/reqless-lib.lua +2965 -0
  14. data/lib/reqless/lua/reqless.lua +2545 -0
  15. data/lib/reqless/lua_script.rb +90 -0
  16. data/lib/reqless/middleware/requeue_exceptions.rb +94 -0
  17. data/lib/reqless/middleware/retry_exceptions.rb +72 -0
  18. data/lib/reqless/middleware/sentry.rb +66 -0
  19. data/lib/reqless/middleware/timeout.rb +63 -0
  20. data/lib/reqless/queue.rb +189 -0
  21. data/lib/reqless/queue_priority_pattern.rb +16 -0
  22. data/lib/reqless/server/static/css/bootstrap-responsive.css +686 -0
  23. data/lib/reqless/server/static/css/bootstrap-responsive.min.css +12 -0
  24. data/lib/reqless/server/static/css/bootstrap.css +3991 -0
  25. data/lib/reqless/server/static/css/bootstrap.min.css +689 -0
  26. data/lib/reqless/server/static/css/codemirror.css +112 -0
  27. data/lib/reqless/server/static/css/docs.css +839 -0
  28. data/lib/reqless/server/static/css/jquery.noty.css +105 -0
  29. data/lib/reqless/server/static/css/noty_theme_twitter.css +137 -0
  30. data/lib/reqless/server/static/css/style.css +200 -0
  31. data/lib/reqless/server/static/favicon.ico +0 -0
  32. data/lib/reqless/server/static/img/glyphicons-halflings-white.png +0 -0
  33. data/lib/reqless/server/static/img/glyphicons-halflings.png +0 -0
  34. data/lib/reqless/server/static/js/bootstrap-alert.js +94 -0
  35. data/lib/reqless/server/static/js/bootstrap-scrollspy.js +125 -0
  36. data/lib/reqless/server/static/js/bootstrap-tab.js +130 -0
  37. data/lib/reqless/server/static/js/bootstrap-tooltip.js +270 -0
  38. data/lib/reqless/server/static/js/bootstrap-typeahead.js +285 -0
  39. data/lib/reqless/server/static/js/bootstrap.js +1726 -0
  40. data/lib/reqless/server/static/js/bootstrap.min.js +6 -0
  41. data/lib/reqless/server/static/js/codemirror.js +2972 -0
  42. data/lib/reqless/server/static/js/jquery.noty.js +220 -0
  43. data/lib/reqless/server/static/js/mode/javascript.js +360 -0
  44. data/lib/reqless/server/static/js/theme/cobalt.css +18 -0
  45. data/lib/reqless/server/static/js/theme/eclipse.css +25 -0
  46. data/lib/reqless/server/static/js/theme/elegant.css +10 -0
  47. data/lib/reqless/server/static/js/theme/lesser-dark.css +45 -0
  48. data/lib/reqless/server/static/js/theme/monokai.css +28 -0
  49. data/lib/reqless/server/static/js/theme/neat.css +9 -0
  50. data/lib/reqless/server/static/js/theme/night.css +21 -0
  51. data/lib/reqless/server/static/js/theme/rubyblue.css +21 -0
  52. data/lib/reqless/server/static/js/theme/xq-dark.css +46 -0
  53. data/lib/reqless/server/views/_job.erb +259 -0
  54. data/lib/reqless/server/views/_job_list.erb +8 -0
  55. data/lib/reqless/server/views/_pagination.erb +7 -0
  56. data/lib/reqless/server/views/about.erb +130 -0
  57. data/lib/reqless/server/views/completed.erb +11 -0
  58. data/lib/reqless/server/views/config.erb +14 -0
  59. data/lib/reqless/server/views/failed.erb +48 -0
  60. data/lib/reqless/server/views/failed_type.erb +18 -0
  61. data/lib/reqless/server/views/job.erb +17 -0
  62. data/lib/reqless/server/views/layout.erb +451 -0
  63. data/lib/reqless/server/views/overview.erb +137 -0
  64. data/lib/reqless/server/views/queue.erb +125 -0
  65. data/lib/reqless/server/views/queues.erb +45 -0
  66. data/lib/reqless/server/views/tag.erb +6 -0
  67. data/lib/reqless/server/views/throttles.erb +38 -0
  68. data/lib/reqless/server/views/track.erb +75 -0
  69. data/lib/reqless/server/views/worker.erb +34 -0
  70. data/lib/reqless/server/views/workers.erb +14 -0
  71. data/lib/reqless/server.rb +549 -0
  72. data/lib/reqless/subscriber.rb +74 -0
  73. data/lib/reqless/test_helpers/worker_helpers.rb +55 -0
  74. data/lib/reqless/throttle.rb +57 -0
  75. data/lib/reqless/version.rb +5 -0
  76. data/lib/reqless/worker/base.rb +237 -0
  77. data/lib/reqless/worker/forking.rb +215 -0
  78. data/lib/reqless/worker/serial.rb +41 -0
  79. data/lib/reqless/worker.rb +5 -0
  80. data/lib/reqless.rb +309 -0
  81. metadata +399 -0
data/lib/reqless.rb ADDED
@@ -0,0 +1,309 @@
1
+ # Encoding: utf-8
2
+
3
+ require 'socket'
4
+ require 'redis'
5
+ require 'json'
6
+ require 'securerandom'
7
+
8
+ module Reqless
9
+ # Define our error base class before requiring the other files so they can
10
+ # define subclasses.
11
+ Error = Class.new(StandardError)
12
+ end
13
+
14
+ require 'reqless/version'
15
+ require 'reqless/config'
16
+ require 'reqless/queue'
17
+ require 'reqless/queue_priority_pattern'
18
+ require 'reqless/throttle'
19
+ require 'reqless/job'
20
+ require 'reqless/lua_script'
21
+ require 'reqless/failure_formatter'
22
+
23
+ module Reqless
24
+ UnsupportedRedisVersionError = Class.new(Error)
25
+
26
+ def generate_jid
27
+ SecureRandom.uuid.gsub('-', '')
28
+ end
29
+
30
+ def stringify_hash_keys(hash)
31
+ hash.each_with_object({}) do |(key, value), result|
32
+ result[key.to_s] = value
33
+ end
34
+ end
35
+
36
+ def failure_formatter
37
+ @failure_formatter ||= FailureFormatter.new
38
+ end
39
+
40
+ module_function :generate_jid, :stringify_hash_keys, :failure_formatter
41
+
42
+ # A class for interacting with jobs. Not meant to be instantiated directly,
43
+ # it's accessed through Client#jobs
44
+ class ClientJobs
45
+ def initialize(client)
46
+ @client = client
47
+ end
48
+
49
+ def complete(offset = 0, count = 25)
50
+ JSON.parse(@client.call('jobs.completed', offset, count))
51
+ end
52
+
53
+ def tracked
54
+ results = JSON.parse(@client.call('jobs.tracked'))
55
+ results['jobs'] = results['jobs'].map { |j| Job.new(@client, j) }
56
+ results
57
+ end
58
+
59
+ def tagged(tag, offset = 0, count = 25)
60
+ results = JSON.parse(@client.call('jobs.tagged', tag, offset, count))
61
+ # Should be an empty array instead of an empty hash
62
+ results['jobs'] = [] if results['jobs'] == {}
63
+ results
64
+ end
65
+
66
+ def failed(t = nil, start = 0, limit = 25)
67
+ if !t
68
+ return JSON.parse(@client.call('failureGroups.counts'))
69
+ else
70
+ results = JSON.parse(@client.call('jobs.failedByGroup', t, start, limit))
71
+ results['jobs'] = multiget(*results['jobs'])
72
+ results
73
+ end
74
+ end
75
+
76
+ def [](id)
77
+ get(id)
78
+ end
79
+
80
+ def get(jid)
81
+ results = @client.call('job.get', jid)
82
+ if results.nil?
83
+ results = @client.call('recurringJob.get', jid)
84
+ return nil if results.nil?
85
+ return RecurringJob.new(@client, JSON.parse(results))
86
+ end
87
+ Job.new(@client, JSON.parse(results))
88
+ end
89
+
90
+ def multiget(*jids)
91
+ results = JSON.parse(@client.call('job.getMulti', *jids))
92
+ results.map do |data|
93
+ Job.new(@client, data)
94
+ end
95
+ end
96
+ end
97
+
98
+ # A class for interacting with workers. Not meant to be instantiated
99
+ # directly, it's accessed through Client#workers
100
+ class ClientWorkers
101
+ def initialize(client)
102
+ @client = client
103
+ end
104
+
105
+ def counts
106
+ JSON.parse(@client.call('workers.counts'))
107
+ end
108
+
109
+ def [](name)
110
+ JSON.parse(@client.call('worker.jobs', name))
111
+ end
112
+ end
113
+
114
+ # A class for interacting with queues. Not meant to be instantiated directly,
115
+ # it's accessed through Client#queues
116
+ class ClientQueues
117
+ def initialize(client)
118
+ @client = client
119
+ end
120
+
121
+ def counts
122
+ JSON.parse(@client.call('queues.counts'))
123
+ end
124
+
125
+ def [](name)
126
+ Queue.new(name, @client)
127
+ end
128
+ end
129
+
130
+ # A class for interacting with throttles. Not meant to be instantiated directly,
131
+ # it's accessed through Client#throttles
132
+ class ClientThrottles
133
+ def initialize(client)
134
+ @client = client
135
+ end
136
+
137
+ def [](name)
138
+ Throttle.new(name, @client)
139
+ end
140
+
141
+ def counts
142
+ @client.queues.counts.map do |queue|
143
+ Queue.new(queue['name'], @client).throttle
144
+ end
145
+ end
146
+ end
147
+
148
+ class ClientQueuePatterns
149
+ def initialize(client)
150
+ @client = client
151
+ end
152
+
153
+ def get_queue_identifier_patterns
154
+ serialized_patterns = @client.call('queueIdentifierPatterns.getAll')
155
+ identifiers_with_serialized_patterns = JSON.parse(serialized_patterns)
156
+ Hash[
157
+ identifiers_with_serialized_patterns.map do |identifier, serialized_pattern|
158
+ [identifier, JSON.parse(serialized_pattern)]
159
+ end
160
+ ]
161
+ end
162
+
163
+ def set_queue_identifier_patterns(identifier_patterns)
164
+ args = identifier_patterns.flat_map do |identifier, pattern|
165
+ [identifier, JSON.dump(pattern)]
166
+ end
167
+ @client.call('queueIdentifierPatterns.setAll', *args)
168
+ end
169
+
170
+ def get_queue_priority_patterns
171
+ serialized_priority_patterns_json = @client.call('queuePriorityPatterns.getAll')
172
+ serialized_priority_patterns = JSON.parse(serialized_priority_patterns_json)
173
+ serialized_priority_patterns.map do |serialized_priority_pattern|
174
+ priority_pattern = JSON.parse(serialized_priority_pattern)
175
+ QueuePriorityPattern.new(
176
+ priority_pattern['pattern'],
177
+ priority_pattern.fetch('fairly', false),
178
+ )
179
+ end
180
+ end
181
+
182
+ def set_queue_priority_patterns(queue_priority_patterns)
183
+ serialized_patterns = queue_priority_patterns.map do |queue_priority_pattern|
184
+ JSON.dump({
185
+ 'pattern': queue_priority_pattern.pattern,
186
+ 'fairly': queue_priority_pattern.should_distribute_fairly,
187
+ })
188
+ end
189
+ @client.call('queuePriorityPatterns.setAll', *serialized_patterns)
190
+ end
191
+ end
192
+
193
+ # A class for interacting with events. Not meant to be instantiated directly,
194
+ # it's accessed through Client#events
195
+ class ClientEvents
196
+ EVENTS = %w{canceled completed failed popped stalled put track untrack}
197
+ EVENTS.each do |method|
198
+ define_method(method.to_sym) do |&block|
199
+ @actions[method.to_sym] = block
200
+ end
201
+ end
202
+
203
+ def initialize(redis)
204
+ @redis = redis
205
+ @actions = {}
206
+ end
207
+
208
+ def listen
209
+ yield(self) if block_given?
210
+ channels = EVENTS.map { |event| "ql:#{event}" }
211
+ @redis.subscribe(channels) do |on|
212
+ on.message do |channel, message|
213
+ callback = @actions[channel.sub('ql:', '').to_sym]
214
+ callback.call(message) unless callback.nil?
215
+ end
216
+ end
217
+ end
218
+
219
+ def stop
220
+ @redis.unsubscribe
221
+ end
222
+ end
223
+
224
+ # The client for interacting with Reqless
225
+ class Client
226
+ attr_reader :_reqless, :config, :redis, :jobs, :queue_patterns, :queues, :throttles, :workers
227
+ attr_accessor :worker_name
228
+
229
+ def initialize(options = {})
230
+ default_options = {:ensure_minimum_version => true}
231
+ options = default_options.merge(options)
232
+
233
+ should_ensure_minimum_redis_version = options.delete(:ensure_minimum_version)
234
+ # This is the redis instance we're connected to. Use connect so REDIS_URL
235
+ # will be honored
236
+ @redis = options[:redis] || Redis.new(options)
237
+ @options = options
238
+ assert_minimum_redis_version('2.5.5') if should_ensure_minimum_redis_version
239
+ @config = Config.new(self)
240
+ @_reqless = Reqless::LuaScript.new('reqless', @redis, :on_reload_callback => @options[:on_lua_script_reload_callback])
241
+
242
+ @jobs = ClientJobs.new(self)
243
+ @queues = ClientQueues.new(self)
244
+ @throttles = ClientThrottles.new(self)
245
+ @queue_patterns = ClientQueuePatterns.new(self)
246
+ @workers = ClientWorkers.new(self)
247
+ @worker_name = [Socket.gethostname, Process.pid.to_s].join('-')
248
+ end
249
+
250
+ def inspect
251
+ "<Reqless::Client #{@options} >"
252
+ end
253
+
254
+ def events
255
+ # Events needs its own redis instance of the same configuration, because
256
+ # once it's subscribed, we can only use pub-sub-like commands. This way,
257
+ # we still have access to the client in the normal case
258
+ @events ||= ClientEvents.new(Redis.new(@options))
259
+ end
260
+
261
+ def call(command, *argv)
262
+ @_reqless.call(command, Time.now.to_f, *argv)
263
+ end
264
+
265
+ def track(jid)
266
+ call('job.track', jid)
267
+ end
268
+
269
+ def untrack(jid)
270
+ call('job.untrack', jid)
271
+ end
272
+
273
+ def tags(offset = 0, count = 100)
274
+ JSON.parse(call('tags.top', offset, count))
275
+ end
276
+
277
+ def deregister_workers(*worker_names)
278
+ call('worker.forget', *worker_names)
279
+ end
280
+
281
+ def bulk_cancel(jids)
282
+ call('job.cancel', jids)
283
+ end
284
+
285
+ def new_redis_connection
286
+ @redis.dup
287
+ end
288
+
289
+ def ==(other)
290
+ self.class == other.class && redis.id == other.redis.id
291
+ end
292
+ alias eql? ==
293
+
294
+ def hash
295
+ self.class.hash ^ redis.id.hash
296
+ end
297
+
298
+ private
299
+
300
+ def assert_minimum_redis_version(version)
301
+ # remove the "-pre2" from "2.6.8-pre2"
302
+ redis_version = @redis.info.fetch('redis_version').split('-').first
303
+ return if Gem::Version.new(redis_version) >= Gem::Version.new(version)
304
+
305
+ raise UnsupportedRedisVersionError,
306
+ "Reqless requires #{version} or better, not #{redis_version}"
307
+ end
308
+ end
309
+ end
metadata ADDED
@@ -0,0 +1,399 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reqless
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dan Lecocq
8
+ - Myron Marston
9
+ - Danny Guinther
10
+ autorequire:
11
+ bindir: exe
12
+ cert_chain: []
13
+ date: 2024-08-25 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: redis
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: 5.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: 5.1.0
29
+ - !ruby/object:Gem::Dependency
30
+ name: capybara
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: 3.40.0
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: 3.40.0
43
+ - !ruby/object:Gem::Dependency
44
+ name: faye-websocket
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 0.11.3
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: 0.11.3
57
+ - !ruby/object:Gem::Dependency
58
+ name: gem-release
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: 2.2.2
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: 2.2.2
71
+ - !ruby/object:Gem::Dependency
72
+ name: launchy
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: 3.0.0
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: 3.0.0
85
+ - !ruby/object:Gem::Dependency
86
+ name: metriks
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '0.9'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - "~>"
97
+ - !ruby/object:Gem::Version
98
+ version: '0.9'
99
+ - !ruby/object:Gem::Dependency
100
+ name: pry
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: 0.14.2
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: 0.14.2
113
+ - !ruby/object:Gem::Dependency
114
+ name: puma
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: 6.4.2
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - "~>"
125
+ - !ruby/object:Gem::Version
126
+ version: 6.4.2
127
+ - !ruby/object:Gem::Dependency
128
+ name: rack
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - "~>"
132
+ - !ruby/object:Gem::Version
133
+ version: 3.0.10
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - "~>"
139
+ - !ruby/object:Gem::Version
140
+ version: 3.0.10
141
+ - !ruby/object:Gem::Dependency
142
+ name: rackup
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - "~>"
146
+ - !ruby/object:Gem::Version
147
+ version: 2.1.0
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - "~>"
153
+ - !ruby/object:Gem::Version
154
+ version: 2.1.0
155
+ - !ruby/object:Gem::Dependency
156
+ name: rake
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: '13.2'
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: '13.2'
169
+ - !ruby/object:Gem::Dependency
170
+ name: rspec
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - "~>"
174
+ - !ruby/object:Gem::Version
175
+ version: '3.13'
176
+ type: :development
177
+ prerelease: false
178
+ version_requirements: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - "~>"
181
+ - !ruby/object:Gem::Version
182
+ version: '3.13'
183
+ - !ruby/object:Gem::Dependency
184
+ name: rubocop
185
+ requirement: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - "~>"
188
+ - !ruby/object:Gem::Version
189
+ version: 0.13.1
190
+ type: :development
191
+ prerelease: false
192
+ version_requirements: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - "~>"
195
+ - !ruby/object:Gem::Version
196
+ version: 0.13.1
197
+ - !ruby/object:Gem::Dependency
198
+ name: rusage
199
+ requirement: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - "~>"
202
+ - !ruby/object:Gem::Version
203
+ version: 0.2.0
204
+ type: :development
205
+ prerelease: false
206
+ version_requirements: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - "~>"
209
+ - !ruby/object:Gem::Version
210
+ version: 0.2.0
211
+ - !ruby/object:Gem::Dependency
212
+ name: selenium-webdriver
213
+ requirement: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - "~>"
216
+ - !ruby/object:Gem::Version
217
+ version: 4.23.0
218
+ type: :development
219
+ prerelease: false
220
+ version_requirements: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - "~>"
223
+ - !ruby/object:Gem::Version
224
+ version: 4.23.0
225
+ - !ruby/object:Gem::Dependency
226
+ name: sentry-raven
227
+ requirement: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - "~>"
230
+ - !ruby/object:Gem::Version
231
+ version: '0.15'
232
+ type: :development
233
+ prerelease: false
234
+ version_requirements: !ruby/object:Gem::Requirement
235
+ requirements:
236
+ - - "~>"
237
+ - !ruby/object:Gem::Version
238
+ version: '0.15'
239
+ - !ruby/object:Gem::Dependency
240
+ name: simplecov
241
+ requirement: !ruby/object:Gem::Requirement
242
+ requirements:
243
+ - - "~>"
244
+ - !ruby/object:Gem::Version
245
+ version: 0.22.0
246
+ type: :development
247
+ prerelease: false
248
+ version_requirements: !ruby/object:Gem::Requirement
249
+ requirements:
250
+ - - "~>"
251
+ - !ruby/object:Gem::Version
252
+ version: 0.22.0
253
+ - !ruby/object:Gem::Dependency
254
+ name: sinatra
255
+ requirement: !ruby/object:Gem::Requirement
256
+ requirements:
257
+ - - "~>"
258
+ - !ruby/object:Gem::Version
259
+ version: 4.0.0
260
+ type: :development
261
+ prerelease: false
262
+ version_requirements: !ruby/object:Gem::Requirement
263
+ requirements:
264
+ - - "~>"
265
+ - !ruby/object:Gem::Version
266
+ version: 4.0.0
267
+ - !ruby/object:Gem::Dependency
268
+ name: timecop
269
+ requirement: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - "~>"
272
+ - !ruby/object:Gem::Version
273
+ version: 0.9.8
274
+ type: :development
275
+ prerelease: false
276
+ version_requirements: !ruby/object:Gem::Requirement
277
+ requirements:
278
+ - - "~>"
279
+ - !ruby/object:Gem::Version
280
+ version: 0.9.8
281
+ description: "\n`reqless` is meant to be a performant alternative to other queueing\nsystems,
282
+ with statistics collection, a browser interface, and\nstrong guarantees about job
283
+ losses.\n\nIt's written as a collection of Lua scipts that are loaded into the\nRedis
284
+ instance to be used, and then executed by the client library.\nAs such, it's intended
285
+ to be extremely easy to port to other languages,\nwithout sacrificing performance
286
+ and not requiring a lot of logic\nreplication between clients. Keep the Lua scripts
287
+ updated, and your\nlanguage-specific extension will also remain up to date.\n "
288
+ email:
289
+ - dan@moz.com
290
+ - myron@moz.com
291
+ - dannyguinther@gmail.com
292
+ executables:
293
+ - reqless-web
294
+ extensions: []
295
+ extra_rdoc_files: []
296
+ files:
297
+ - Gemfile
298
+ - README.md
299
+ - Rakefile
300
+ - bin/docker-build-and-test
301
+ - exe/reqless-web
302
+ - lib/reqless.rb
303
+ - lib/reqless/config.rb
304
+ - lib/reqless/failure_formatter.rb
305
+ - lib/reqless/job.rb
306
+ - lib/reqless/job_reservers/ordered.rb
307
+ - lib/reqless/job_reservers/round_robin.rb
308
+ - lib/reqless/job_reservers/shuffled_round_robin.rb
309
+ - lib/reqless/lua/reqless-lib.lua
310
+ - lib/reqless/lua/reqless.lua
311
+ - lib/reqless/lua_script.rb
312
+ - lib/reqless/middleware/requeue_exceptions.rb
313
+ - lib/reqless/middleware/retry_exceptions.rb
314
+ - lib/reqless/middleware/sentry.rb
315
+ - lib/reqless/middleware/timeout.rb
316
+ - lib/reqless/queue.rb
317
+ - lib/reqless/queue_priority_pattern.rb
318
+ - lib/reqless/server.rb
319
+ - lib/reqless/server/static/css/bootstrap-responsive.css
320
+ - lib/reqless/server/static/css/bootstrap-responsive.min.css
321
+ - lib/reqless/server/static/css/bootstrap.css
322
+ - lib/reqless/server/static/css/bootstrap.min.css
323
+ - lib/reqless/server/static/css/codemirror.css
324
+ - lib/reqless/server/static/css/docs.css
325
+ - lib/reqless/server/static/css/jquery.noty.css
326
+ - lib/reqless/server/static/css/noty_theme_twitter.css
327
+ - lib/reqless/server/static/css/style.css
328
+ - lib/reqless/server/static/favicon.ico
329
+ - lib/reqless/server/static/img/glyphicons-halflings-white.png
330
+ - lib/reqless/server/static/img/glyphicons-halflings.png
331
+ - lib/reqless/server/static/js/bootstrap-alert.js
332
+ - lib/reqless/server/static/js/bootstrap-scrollspy.js
333
+ - lib/reqless/server/static/js/bootstrap-tab.js
334
+ - lib/reqless/server/static/js/bootstrap-tooltip.js
335
+ - lib/reqless/server/static/js/bootstrap-typeahead.js
336
+ - lib/reqless/server/static/js/bootstrap.js
337
+ - lib/reqless/server/static/js/bootstrap.min.js
338
+ - lib/reqless/server/static/js/codemirror.js
339
+ - lib/reqless/server/static/js/jquery.noty.js
340
+ - lib/reqless/server/static/js/mode/javascript.js
341
+ - lib/reqless/server/static/js/theme/cobalt.css
342
+ - lib/reqless/server/static/js/theme/eclipse.css
343
+ - lib/reqless/server/static/js/theme/elegant.css
344
+ - lib/reqless/server/static/js/theme/lesser-dark.css
345
+ - lib/reqless/server/static/js/theme/monokai.css
346
+ - lib/reqless/server/static/js/theme/neat.css
347
+ - lib/reqless/server/static/js/theme/night.css
348
+ - lib/reqless/server/static/js/theme/rubyblue.css
349
+ - lib/reqless/server/static/js/theme/xq-dark.css
350
+ - lib/reqless/server/views/_job.erb
351
+ - lib/reqless/server/views/_job_list.erb
352
+ - lib/reqless/server/views/_pagination.erb
353
+ - lib/reqless/server/views/about.erb
354
+ - lib/reqless/server/views/completed.erb
355
+ - lib/reqless/server/views/config.erb
356
+ - lib/reqless/server/views/failed.erb
357
+ - lib/reqless/server/views/failed_type.erb
358
+ - lib/reqless/server/views/job.erb
359
+ - lib/reqless/server/views/layout.erb
360
+ - lib/reqless/server/views/overview.erb
361
+ - lib/reqless/server/views/queue.erb
362
+ - lib/reqless/server/views/queues.erb
363
+ - lib/reqless/server/views/tag.erb
364
+ - lib/reqless/server/views/throttles.erb
365
+ - lib/reqless/server/views/track.erb
366
+ - lib/reqless/server/views/worker.erb
367
+ - lib/reqless/server/views/workers.erb
368
+ - lib/reqless/subscriber.rb
369
+ - lib/reqless/test_helpers/worker_helpers.rb
370
+ - lib/reqless/throttle.rb
371
+ - lib/reqless/version.rb
372
+ - lib/reqless/worker.rb
373
+ - lib/reqless/worker/base.rb
374
+ - lib/reqless/worker/forking.rb
375
+ - lib/reqless/worker/serial.rb
376
+ homepage: http://github.com/tdg5/reqless-rb
377
+ licenses:
378
+ - MIT
379
+ metadata: {}
380
+ post_install_message:
381
+ rdoc_options: []
382
+ require_paths:
383
+ - lib
384
+ required_ruby_version: !ruby/object:Gem::Requirement
385
+ requirements:
386
+ - - ">="
387
+ - !ruby/object:Gem::Version
388
+ version: '3.0'
389
+ required_rubygems_version: !ruby/object:Gem::Requirement
390
+ requirements:
391
+ - - ">="
392
+ - !ruby/object:Gem::Version
393
+ version: '0'
394
+ requirements: []
395
+ rubygems_version: 3.5.3
396
+ signing_key:
397
+ specification_version: 4
398
+ summary: A Redis-Based Queueing System
399
+ test_files: []