resque 1.26.0 → 1.27.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of resque might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/HISTORY.md +10 -2
- data/README.markdown +3 -3
- data/lib/resque.rb +34 -35
- data/lib/resque/data_store.rb +326 -0
- data/lib/resque/errors.rb +8 -1
- data/lib/resque/failure.rb +1 -1
- data/lib/resque/failure/airbrake.rb +1 -1
- data/lib/resque/failure/base.rb +4 -4
- data/lib/resque/failure/multiple.rb +4 -0
- data/lib/resque/failure/redis.rb +20 -9
- data/lib/resque/failure/redis_multi_queue.rb +17 -10
- data/lib/resque/job.rb +8 -4
- data/lib/resque/server.rb +1 -1
- data/lib/resque/server/helpers.rb +13 -1
- data/lib/resque/server/public/jquery-1.12.4.min.js +5 -0
- data/lib/resque/server/views/failed.erb +3 -3
- data/lib/resque/server/views/key_sets.erb +1 -3
- data/lib/resque/server/views/layout.erb +2 -2
- data/lib/resque/server/views/queues.erb +1 -1
- data/lib/resque/server/views/working.erb +3 -2
- data/lib/resque/stat.rb +5 -4
- data/lib/resque/tasks.rb +14 -7
- data/lib/resque/thread_signal.rb +45 -0
- data/lib/resque/version.rb +1 -1
- data/lib/resque/worker.rb +129 -112
- data/lib/tasks/redis.rake +1 -1
- metadata +60 -57
- data/lib/resque/server/public/jquery-1.3.2.min.js +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5f0cb00378f55254a8f68c68fed023ea569e1a8
|
4
|
+
data.tar.gz: bf7219b392370ef84f16ab57ff3646c64544a17d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd8e4634086ea6c5f5147799d35596924abb49a71fa1c99223017c4ade6b24b5afba32f2e70985b18af6493530fd554ecd76947a7f7ff04f32e5aeb43c707477
|
7
|
+
data.tar.gz: 484db5ed7b0b3be036c9523a2720a16edaa43748a65d34a2add2932784fc37440e0922596529b229d471177c03599df65ab7d57b980b99850c39ab98dfe26e4f
|
data/HISTORY.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
-
## 1.
|
1
|
+
## 1.28.0 (TBD)
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
## 1.27.0 (2017-02-08)
|
5
|
+
|
6
|
+
* Update jQuery from 1.3.2 to 1.12.4
|
7
|
+
|
8
|
+
* Fix issue where calling Worker.find, Worker.all, or Worker.working from withing
|
9
|
+
a running job would rewrite the PID file with the PID of the forked worker.
|
10
|
+
This causes a change to the Worker#new API that may affect plugin
|
11
|
+
implementations. See Worker#new and Worker#prepare for details. (@jeremywadsack)
|
4
12
|
|
5
13
|
## 1.26.0 (2016-03-10)
|
6
14
|
|
data/README.markdown
CHANGED
@@ -524,8 +524,8 @@ or set the Redis connection string if you need to do something like select a dif
|
|
524
524
|
Using Passenger? Resque ships with a `config.ru` you can use. See
|
525
525
|
Phusion's guide:
|
526
526
|
|
527
|
-
Apache: <
|
528
|
-
Nginx: <
|
527
|
+
Apache: <https://www.phusionpassenger.com/library/deploy/apache/deploy/ruby/>
|
528
|
+
Nginx: <https://www.phusionpassenger.com/library/deploy/nginx/deploy/ruby/>
|
529
529
|
|
530
530
|
### Rack::URLMap
|
531
531
|
|
@@ -687,7 +687,7 @@ Don't forget you can define a `resque:setup` hook in
|
|
687
687
|
`lib/tasks/whatever.rake` that loads the `environment` task every time.
|
688
688
|
|
689
689
|
|
690
|
-
### In a Rails 3 app, as a gem
|
690
|
+
### In a Rails 3.x or 4.x app, as a gem
|
691
691
|
|
692
692
|
First include it in your Gemfile.
|
693
693
|
|
data/lib/resque.rb
CHANGED
@@ -18,6 +18,8 @@ require 'resque/log_formatters/very_verbose_formatter'
|
|
18
18
|
require 'resque/job'
|
19
19
|
require 'resque/worker'
|
20
20
|
require 'resque/plugin'
|
21
|
+
require 'resque/data_store'
|
22
|
+
require 'resque/thread_signal'
|
21
23
|
|
22
24
|
require 'resque/vendor/utf8_util'
|
23
25
|
|
@@ -120,33 +122,29 @@ module Resque
|
|
120
122
|
end
|
121
123
|
namespace ||= :resque
|
122
124
|
|
123
|
-
@
|
125
|
+
@data_store = Resque::DataStore.new(Redis::Namespace.new(namespace, :redis => redis))
|
124
126
|
when Redis::Namespace
|
125
|
-
@
|
127
|
+
@data_store = Resque::DataStore.new(server)
|
128
|
+
when Resque::DataStore
|
129
|
+
@data_store = server
|
126
130
|
when Hash
|
127
|
-
@
|
131
|
+
@data_store = Resque::DataStore.new(Redis::Namespace.new(:resque, :redis => Redis.new(server)))
|
128
132
|
else
|
129
|
-
@
|
133
|
+
@data_store = Resque::DataStore.new(Redis::Namespace.new(:resque, :redis => server))
|
130
134
|
end
|
131
135
|
end
|
132
136
|
|
133
137
|
# Returns the current Redis connection. If none has been created, will
|
134
138
|
# create a new one.
|
135
139
|
def redis
|
136
|
-
return @
|
140
|
+
return @data_store if @data_store
|
137
141
|
self.redis = Redis.respond_to?(:connect) ? Redis.connect : "localhost:6379"
|
138
142
|
self.redis
|
139
143
|
end
|
144
|
+
alias :data_store :redis
|
140
145
|
|
141
146
|
def redis_id
|
142
|
-
|
143
|
-
if redis.respond_to?(:server)
|
144
|
-
redis.server
|
145
|
-
elsif redis.respond_to?(:nodes) # distributed
|
146
|
-
redis.nodes.map { |n| n.id }.join(', ')
|
147
|
-
else
|
148
|
-
redis.client.id
|
149
|
-
end
|
147
|
+
data_store.identifier
|
150
148
|
end
|
151
149
|
|
152
150
|
# Set or retrieve the current logger object
|
@@ -165,6 +163,12 @@ module Resque
|
|
165
163
|
@prune_interval || DEFAULT_PRUNE_INTERVAL
|
166
164
|
end
|
167
165
|
|
166
|
+
attr_writer :enqueue_front
|
167
|
+
def enqueue_front
|
168
|
+
return @enqueue_front unless @enqueue_front.nil?
|
169
|
+
@enqueue_front = false
|
170
|
+
end
|
171
|
+
|
168
172
|
# The `before_first_fork` hook will be run in the **parent** process
|
169
173
|
# only once, before forking to run the first job. Be careful- any
|
170
174
|
# changes you make will be permanent for the lifespan of the
|
@@ -264,24 +268,20 @@ module Resque
|
|
264
268
|
#
|
265
269
|
# Returns nothing
|
266
270
|
def push(queue, item)
|
267
|
-
|
268
|
-
redis.pipelined do
|
269
|
-
watch_queue(queue)
|
270
|
-
redis.rpush "queue:#{queue}", encoded
|
271
|
-
end
|
271
|
+
data_store.push_to_queue(queue,encode(item))
|
272
272
|
end
|
273
273
|
|
274
274
|
# Pops a job off a queue. Queue name should be a string.
|
275
275
|
#
|
276
276
|
# Returns a Ruby object.
|
277
277
|
def pop(queue)
|
278
|
-
decode
|
278
|
+
decode(data_store.pop_from_queue(queue))
|
279
279
|
end
|
280
280
|
|
281
281
|
# Returns an integer representing the size of a queue.
|
282
282
|
# Queue name should be a string.
|
283
283
|
def size(queue)
|
284
|
-
|
284
|
+
data_store.queue_size(queue)
|
285
285
|
end
|
286
286
|
|
287
287
|
# Returns an array of items currently queued. Queue name should be
|
@@ -293,38 +293,39 @@ module Resque
|
|
293
293
|
# To get the 3rd page of a 30 item, paginatied list one would use:
|
294
294
|
# Resque.peek('my_list', 59, 30)
|
295
295
|
def peek(queue, start = 0, count = 1)
|
296
|
-
|
296
|
+
results = data_store.peek_in_queue(queue,start,count)
|
297
|
+
if count == 1
|
298
|
+
decode(results)
|
299
|
+
else
|
300
|
+
results.map { |result| decode(result) }
|
301
|
+
end
|
297
302
|
end
|
298
303
|
|
299
304
|
# Does the dirty work of fetching a range of items from a Redis list
|
300
305
|
# and converting them into Ruby objects.
|
301
306
|
def list_range(key, start = 0, count = 1)
|
307
|
+
results = data_store.list_range(key, start, count)
|
302
308
|
if count == 1
|
303
|
-
decode
|
309
|
+
decode(results)
|
304
310
|
else
|
305
|
-
|
306
|
-
decode item
|
307
|
-
end
|
311
|
+
results.map { |result| decode(result) }
|
308
312
|
end
|
309
313
|
end
|
310
314
|
|
311
315
|
# Returns an array of all known Resque queues as strings.
|
312
316
|
def queues
|
313
|
-
|
317
|
+
data_store.queue_names
|
314
318
|
end
|
315
319
|
|
316
320
|
# Given a queue name, completely deletes the queue.
|
317
321
|
def remove_queue(queue)
|
318
|
-
|
319
|
-
redis.srem(:queues, queue.to_s)
|
320
|
-
redis.del("queue:#{queue}")
|
321
|
-
end
|
322
|
+
data_store.remove_queue(queue)
|
322
323
|
end
|
323
324
|
|
324
325
|
# Used internally to keep track of which queues we've created.
|
325
326
|
# Don't call this directly.
|
326
327
|
def watch_queue(queue)
|
327
|
-
|
328
|
+
data_store.watch_queue(queue)
|
328
329
|
end
|
329
330
|
|
330
331
|
|
@@ -487,7 +488,7 @@ module Resque
|
|
487
488
|
:queues => queues.size,
|
488
489
|
:workers => workers.size.to_i,
|
489
490
|
:working => working.size,
|
490
|
-
:failed =>
|
491
|
+
:failed => data_store.num_failed,
|
491
492
|
:servers => [redis_id],
|
492
493
|
:environment => ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
493
494
|
}
|
@@ -496,9 +497,7 @@ module Resque
|
|
496
497
|
# Returns an array of all known Resque keys in Redis. Redis' KEYS operation
|
497
498
|
# is O(N) for the keyspace, so be careful - this can be slow for big databases.
|
498
499
|
def keys
|
499
|
-
|
500
|
-
key.sub("#{redis.namespace}:", '')
|
501
|
-
end
|
500
|
+
data_store.all_resque_keys
|
502
501
|
end
|
503
502
|
|
504
503
|
# Returns a hash, mapping queue names to queue sizes
|
@@ -0,0 +1,326 @@
|
|
1
|
+
module Resque
|
2
|
+
# An interface between Resque's persistence and the actual
|
3
|
+
# implementation.
|
4
|
+
class DataStore
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
HEARTBEAT_KEY = "workers:heartbeat"
|
8
|
+
|
9
|
+
def initialize(redis)
|
10
|
+
@redis = redis
|
11
|
+
@queue_access = QueueAccess.new(@redis)
|
12
|
+
@failed_queue_access = FailedQueueAccess.new(@redis)
|
13
|
+
@workers = Workers.new(@redis)
|
14
|
+
@stats_access = StatsAccess.new(@redis)
|
15
|
+
end
|
16
|
+
|
17
|
+
def_delegators :@queue_access, :push_to_queue,
|
18
|
+
:pop_from_queue,
|
19
|
+
:queue_size,
|
20
|
+
:peek_in_queue,
|
21
|
+
:queue_names,
|
22
|
+
:remove_queue,
|
23
|
+
:everything_in_queue,
|
24
|
+
:remove_from_queue,
|
25
|
+
:watch_queue,
|
26
|
+
:list_range
|
27
|
+
|
28
|
+
def_delegators :@failed_queue_access, :add_failed_queue,
|
29
|
+
:remove_failed_queue,
|
30
|
+
:num_failed,
|
31
|
+
:failed_queue_names,
|
32
|
+
:push_to_failed_queue,
|
33
|
+
:clear_failed_queue,
|
34
|
+
:update_item_in_failed_queue,
|
35
|
+
:remove_from_failed_queue
|
36
|
+
def_delegators :@workers, :worker_ids,
|
37
|
+
:workers_map,
|
38
|
+
:get_worker_payload,
|
39
|
+
:worker_exists?,
|
40
|
+
:register_worker,
|
41
|
+
:worker_started,
|
42
|
+
:unregister_worker,
|
43
|
+
:heartbeat,
|
44
|
+
:heartbeat!,
|
45
|
+
:remove_heartbeat,
|
46
|
+
:all_heartbeats,
|
47
|
+
:set_worker_payload,
|
48
|
+
:worker_start_time,
|
49
|
+
:worker_done_working
|
50
|
+
|
51
|
+
def_delegators :@stats_access, :clear_stat,
|
52
|
+
:decremet_stat,
|
53
|
+
:increment_stat,
|
54
|
+
:stat
|
55
|
+
|
56
|
+
# Compatibility with any non-Resque classes that were using Resque.redis as a way to access Redis
|
57
|
+
def method_missing(sym,*args,&block)
|
58
|
+
# TODO: deprecation warning?
|
59
|
+
@redis.send(sym,*args,&block)
|
60
|
+
end
|
61
|
+
|
62
|
+
# make use respond like redis
|
63
|
+
def respond_to?(method,include_all=false)
|
64
|
+
@redis.respond_to?(method,include_all)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Get a string identifying the underlying server.
|
68
|
+
# Probably should be private, but was public so must stay public
|
69
|
+
def identifier
|
70
|
+
# support 1.x versions of redis-rb
|
71
|
+
if @redis.respond_to?(:server)
|
72
|
+
@redis.server
|
73
|
+
elsif @redis.respond_to?(:nodes) # distributed
|
74
|
+
@redis.nodes.map { |n| n.id }.join(', ')
|
75
|
+
else
|
76
|
+
@redis.client.id
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Force a reconnect to Redis.
|
81
|
+
def reconnect
|
82
|
+
@redis.client.reconnect
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns an array of all known Resque keys in Redis. Redis' KEYS operation
|
86
|
+
# is O(N) for the keyspace, so be careful - this can be slow for big databases.
|
87
|
+
def all_resque_keys
|
88
|
+
@redis.keys("*").map do |key|
|
89
|
+
key.sub("#{@redis.namespace}:", '')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def server_time
|
94
|
+
time, _ = @redis.time
|
95
|
+
Time.at(time)
|
96
|
+
end
|
97
|
+
|
98
|
+
class QueueAccess
|
99
|
+
def initialize(redis)
|
100
|
+
@redis = redis
|
101
|
+
end
|
102
|
+
def push_to_queue(queue,encoded_item)
|
103
|
+
@redis.pipelined do
|
104
|
+
watch_queue(queue)
|
105
|
+
@redis.rpush redis_key_for_queue(queue), encoded_item
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Pop whatever is on queue
|
110
|
+
def pop_from_queue(queue)
|
111
|
+
@redis.lpop(redis_key_for_queue(queue))
|
112
|
+
end
|
113
|
+
|
114
|
+
# Get the number of items in the queue
|
115
|
+
def queue_size(queue)
|
116
|
+
@redis.llen(redis_key_for_queue(queue)).to_i
|
117
|
+
end
|
118
|
+
|
119
|
+
# Examine items in the queue.
|
120
|
+
#
|
121
|
+
# NOTE: if count is 1, you will get back an object, otherwise you will
|
122
|
+
# get an Array. I'm not making this up.
|
123
|
+
def peek_in_queue(queue, start = 0, count = 1)
|
124
|
+
list_range(redis_key_for_queue(queue), start, count)
|
125
|
+
end
|
126
|
+
|
127
|
+
def queue_names
|
128
|
+
Array(@redis.smembers(:queues))
|
129
|
+
end
|
130
|
+
|
131
|
+
def remove_queue(queue)
|
132
|
+
@redis.pipelined do
|
133
|
+
@redis.srem(:queues, queue.to_s)
|
134
|
+
@redis.del(redis_key_for_queue(queue))
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def everything_in_queue(queue)
|
139
|
+
@redis.lrange(redis_key_for_queue(queue), 0, -1)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Remove data from the queue, if it's there, returning the number of removed elements
|
143
|
+
def remove_from_queue(queue,data)
|
144
|
+
@redis.lrem(redis_key_for_queue(queue), 0, data)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Private: do not call
|
148
|
+
def watch_queue(queue)
|
149
|
+
@redis.sadd(:queues, queue.to_s)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Private: do not call
|
153
|
+
def list_range(key, start = 0, count = 1)
|
154
|
+
if count == 1
|
155
|
+
@redis.lindex(key, start)
|
156
|
+
else
|
157
|
+
Array(@redis.lrange(key, start, start+count-1))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def redis_key_for_queue(queue)
|
164
|
+
"queue:#{queue}"
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
class FailedQueueAccess
|
170
|
+
def initialize(redis)
|
171
|
+
@redis = redis
|
172
|
+
end
|
173
|
+
|
174
|
+
def add_failed_queue(failed_queue_name)
|
175
|
+
@redis.sadd(:failed_queues, failed_queue_name)
|
176
|
+
end
|
177
|
+
|
178
|
+
def remove_failed_queue(failed_queue_name=:failed)
|
179
|
+
@redis.del(failed_queue_name)
|
180
|
+
end
|
181
|
+
|
182
|
+
def num_failed(failed_queue_name=:failed)
|
183
|
+
@redis.llen(failed_queue_name).to_i
|
184
|
+
end
|
185
|
+
|
186
|
+
def failed_queue_names(find_queue_names_in_key=nil)
|
187
|
+
if find_queue_names_in_key.nil?
|
188
|
+
[:failed]
|
189
|
+
else
|
190
|
+
Array(@redis.smembers(find_queue_names_in_key))
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def push_to_failed_queue(data,failed_queue_name=:failed)
|
195
|
+
@redis.rpush(failed_queue_name,data)
|
196
|
+
end
|
197
|
+
|
198
|
+
def clear_failed_queue(failed_queue_name=:failed)
|
199
|
+
@redis.del(failed_queue_name)
|
200
|
+
end
|
201
|
+
|
202
|
+
def update_item_in_failed_queue(index_in_failed_queue,new_item_data,failed_queue_name=:failed)
|
203
|
+
@redis.lset(failed_queue_name, index_in_failed_queue, new_item_data)
|
204
|
+
end
|
205
|
+
|
206
|
+
def remove_from_failed_queue(index_in_failed_queue,failed_queue_name=nil)
|
207
|
+
failed_queue_name ||= :failed
|
208
|
+
hopefully_unique_value_we_can_use_to_delete_job = ""
|
209
|
+
@redis.lset(failed_queue_name, index_in_failed_queue, hopefully_unique_value_we_can_use_to_delete_job)
|
210
|
+
@redis.lrem(failed_queue_name, 1, hopefully_unique_value_we_can_use_to_delete_job)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
class Workers
|
215
|
+
def initialize(redis)
|
216
|
+
@redis = redis
|
217
|
+
end
|
218
|
+
|
219
|
+
def worker_ids
|
220
|
+
Array(@redis.smembers(:workers))
|
221
|
+
end
|
222
|
+
|
223
|
+
# Given a list of worker ids, returns a map of those ids to the worker's value
|
224
|
+
# in redis, even if that value maps to nil
|
225
|
+
def workers_map(worker_ids)
|
226
|
+
redis_keys = worker_ids.map { |id| "worker:#{id}" }
|
227
|
+
@redis.mapped_mget(*redis_keys)
|
228
|
+
end
|
229
|
+
|
230
|
+
# return the worker's payload i.e. job
|
231
|
+
def get_worker_payload(worker_id)
|
232
|
+
@redis.get("worker:#{worker_id}")
|
233
|
+
end
|
234
|
+
|
235
|
+
def worker_exists?(worker_id)
|
236
|
+
@redis.sismember(:workers, worker_id)
|
237
|
+
end
|
238
|
+
|
239
|
+
def register_worker(worker)
|
240
|
+
@redis.pipelined do
|
241
|
+
@redis.sadd(:workers, worker)
|
242
|
+
worker_started(worker)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def worker_started(worker)
|
247
|
+
@redis.set(redis_key_for_worker_start_time(worker), Time.now.to_s)
|
248
|
+
end
|
249
|
+
|
250
|
+
def unregister_worker(worker, &block)
|
251
|
+
@redis.pipelined do
|
252
|
+
@redis.srem(:workers, worker)
|
253
|
+
@redis.del(redis_key_for_worker(worker))
|
254
|
+
@redis.del(redis_key_for_worker_start_time(worker))
|
255
|
+
@redis.hdel(HEARTBEAT_KEY, worker.to_s)
|
256
|
+
|
257
|
+
block.call
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def remove_heartbeat(worker)
|
262
|
+
@redis.hdel(HEARTBEAT_KEY, worker.to_s)
|
263
|
+
end
|
264
|
+
|
265
|
+
def heartbeat(worker)
|
266
|
+
heartbeat = @redis.hget(HEARTBEAT_KEY, worker.to_s)
|
267
|
+
heartbeat && Time.parse(heartbeat)
|
268
|
+
end
|
269
|
+
|
270
|
+
def heartbeat!(worker, time)
|
271
|
+
@redis.hset(HEARTBEAT_KEY, worker.to_s, time.iso8601)
|
272
|
+
end
|
273
|
+
|
274
|
+
def all_heartbeats
|
275
|
+
@redis.hgetall(HEARTBEAT_KEY)
|
276
|
+
end
|
277
|
+
|
278
|
+
def set_worker_payload(worker, data)
|
279
|
+
@redis.set(redis_key_for_worker(worker), data)
|
280
|
+
end
|
281
|
+
|
282
|
+
def worker_start_time(worker)
|
283
|
+
@redis.get(redis_key_for_worker_start_time(worker))
|
284
|
+
end
|
285
|
+
|
286
|
+
def worker_done_working(worker, &block)
|
287
|
+
@redis.pipelined do
|
288
|
+
@redis.del(redis_key_for_worker(worker))
|
289
|
+
block.call
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
private
|
294
|
+
|
295
|
+
def redis_key_for_worker(worker)
|
296
|
+
"worker:#{worker}"
|
297
|
+
end
|
298
|
+
|
299
|
+
def redis_key_for_worker_start_time(worker)
|
300
|
+
"#{redis_key_for_worker(worker)}:started"
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
class StatsAccess
|
306
|
+
def initialize(redis)
|
307
|
+
@redis = redis
|
308
|
+
end
|
309
|
+
def stat(stat)
|
310
|
+
@redis.get("stat:#{stat}").to_i
|
311
|
+
end
|
312
|
+
|
313
|
+
def increment_stat(stat, by = 1)
|
314
|
+
@redis.incrby("stat:#{stat}", by)
|
315
|
+
end
|
316
|
+
|
317
|
+
def decremet_stat(stat, by = 1)
|
318
|
+
@redis.decrby("stat:#{stat}", by)
|
319
|
+
end
|
320
|
+
|
321
|
+
def clear_stat(stat)
|
322
|
+
@redis.del("stat:#{stat}")
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|