resque-cedar 1.20.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.
- data/HISTORY.md +354 -0
- data/LICENSE +20 -0
- data/README.markdown +908 -0
- data/Rakefile +70 -0
- data/bin/resque +81 -0
- data/bin/resque-web +27 -0
- data/lib/resque.rb +385 -0
- data/lib/resque/coder.rb +27 -0
- data/lib/resque/errors.rb +10 -0
- data/lib/resque/failure.rb +96 -0
- data/lib/resque/failure/airbrake.rb +17 -0
- data/lib/resque/failure/base.rb +64 -0
- data/lib/resque/failure/hoptoad.rb +33 -0
- data/lib/resque/failure/multiple.rb +54 -0
- data/lib/resque/failure/redis.rb +51 -0
- data/lib/resque/failure/thoughtbot.rb +33 -0
- data/lib/resque/helpers.rb +64 -0
- data/lib/resque/job.rb +223 -0
- data/lib/resque/multi_json_coder.rb +37 -0
- data/lib/resque/multi_queue.rb +73 -0
- data/lib/resque/plugin.rb +66 -0
- data/lib/resque/queue.rb +117 -0
- data/lib/resque/server.rb +248 -0
- data/lib/resque/server/public/favicon.ico +0 -0
- data/lib/resque/server/public/idle.png +0 -0
- data/lib/resque/server/public/jquery-1.3.2.min.js +19 -0
- data/lib/resque/server/public/jquery.relatize_date.js +95 -0
- data/lib/resque/server/public/poll.png +0 -0
- data/lib/resque/server/public/ranger.js +73 -0
- data/lib/resque/server/public/reset.css +44 -0
- data/lib/resque/server/public/style.css +86 -0
- data/lib/resque/server/public/working.png +0 -0
- data/lib/resque/server/test_helper.rb +19 -0
- data/lib/resque/server/views/error.erb +1 -0
- data/lib/resque/server/views/failed.erb +67 -0
- data/lib/resque/server/views/key_sets.erb +19 -0
- data/lib/resque/server/views/key_string.erb +11 -0
- data/lib/resque/server/views/layout.erb +44 -0
- data/lib/resque/server/views/next_more.erb +10 -0
- data/lib/resque/server/views/overview.erb +4 -0
- data/lib/resque/server/views/queues.erb +49 -0
- data/lib/resque/server/views/stats.erb +62 -0
- data/lib/resque/server/views/workers.erb +109 -0
- data/lib/resque/server/views/working.erb +72 -0
- data/lib/resque/stat.rb +53 -0
- data/lib/resque/tasks.rb +61 -0
- data/lib/resque/version.rb +3 -0
- data/lib/resque/worker.rb +557 -0
- data/lib/tasks/redis.rake +161 -0
- data/lib/tasks/resque.rake +2 -0
- data/test/airbrake_test.rb +26 -0
- data/test/hoptoad_test.rb +26 -0
- data/test/job_hooks_test.rb +423 -0
- data/test/job_plugins_test.rb +230 -0
- data/test/multi_queue_test.rb +95 -0
- data/test/plugin_test.rb +116 -0
- data/test/redis-test-cluster.conf +115 -0
- data/test/redis-test.conf +115 -0
- data/test/redis_queue_test.rb +133 -0
- data/test/resque-web_test.rb +59 -0
- data/test/resque_test.rb +284 -0
- data/test/test_helper.rb +135 -0
- data/test/worker_test.rb +443 -0
- metadata +188 -0
data/lib/resque/job.rb
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
module Resque
|
2
|
+
# A Resque::Job represents a unit of work. Each job lives on a
|
3
|
+
# single queue and has an associated payload object. The payload
|
4
|
+
# is a hash with two attributes: `class` and `args`. The `class` is
|
5
|
+
# the name of the Ruby class which should be used to run the
|
6
|
+
# job. The `args` are an array of arguments which should be passed
|
7
|
+
# to the Ruby class's `perform` class-level method.
|
8
|
+
#
|
9
|
+
# You can manually run a job using this code:
|
10
|
+
#
|
11
|
+
# job = Resque::Job.reserve(:high)
|
12
|
+
# klass = Resque::Job.constantize(job.payload['class'])
|
13
|
+
# klass.perform(*job.payload['args'])
|
14
|
+
class Job
|
15
|
+
include Helpers
|
16
|
+
extend Helpers
|
17
|
+
|
18
|
+
# Raise Resque::Job::DontPerform from a before_perform hook to
|
19
|
+
# abort the job.
|
20
|
+
DontPerform = Class.new(StandardError)
|
21
|
+
|
22
|
+
# The worker object which is currently processing this job.
|
23
|
+
attr_accessor :worker
|
24
|
+
|
25
|
+
# The name of the queue from which this job was pulled (or is to be
|
26
|
+
# placed)
|
27
|
+
attr_reader :queue
|
28
|
+
|
29
|
+
# This job's associated payload object.
|
30
|
+
attr_reader :payload
|
31
|
+
|
32
|
+
def initialize(queue, payload)
|
33
|
+
@queue = queue
|
34
|
+
@payload = payload
|
35
|
+
end
|
36
|
+
|
37
|
+
# Creates a job by placing it on a queue. Expects a string queue
|
38
|
+
# name, a string class name, and an optional array of arguments to
|
39
|
+
# pass to the class' `perform` method.
|
40
|
+
#
|
41
|
+
# Raises an exception if no queue or class is given.
|
42
|
+
def self.create(queue, klass, *args)
|
43
|
+
Resque.validate(klass, queue)
|
44
|
+
|
45
|
+
if Resque.inline?
|
46
|
+
constantize(klass).perform(*decode(encode(args)))
|
47
|
+
else
|
48
|
+
Resque.push(queue, :class => klass.to_s, :args => args)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Removes a job from a queue. Expects a string queue name, a
|
53
|
+
# string class name, and, optionally, args.
|
54
|
+
#
|
55
|
+
# Returns the number of jobs destroyed.
|
56
|
+
#
|
57
|
+
# If no args are provided, it will remove all jobs of the class
|
58
|
+
# provided.
|
59
|
+
#
|
60
|
+
# That is, for these two jobs:
|
61
|
+
#
|
62
|
+
# { 'class' => 'UpdateGraph', 'args' => ['defunkt'] }
|
63
|
+
# { 'class' => 'UpdateGraph', 'args' => ['mojombo'] }
|
64
|
+
#
|
65
|
+
# The following call will remove both:
|
66
|
+
#
|
67
|
+
# Resque::Job.destroy(queue, 'UpdateGraph')
|
68
|
+
#
|
69
|
+
# Whereas specifying args will only remove the 2nd job:
|
70
|
+
#
|
71
|
+
# Resque::Job.destroy(queue, 'UpdateGraph', 'mojombo')
|
72
|
+
#
|
73
|
+
# This method can be potentially very slow and memory intensive,
|
74
|
+
# depending on the size of your queue, as it loads all jobs into
|
75
|
+
# a Ruby array before processing.
|
76
|
+
def self.destroy(queue, klass, *args)
|
77
|
+
klass = klass.to_s
|
78
|
+
queue = "queue:#{queue}"
|
79
|
+
destroyed = 0
|
80
|
+
|
81
|
+
if args.empty?
|
82
|
+
redis.lrange(queue, 0, -1).each do |string|
|
83
|
+
if decode(string)['class'] == klass
|
84
|
+
destroyed += redis.lrem(queue, 0, string).to_i
|
85
|
+
end
|
86
|
+
end
|
87
|
+
else
|
88
|
+
destroyed += redis.lrem(queue, 0, encode(:class => klass, :args => args))
|
89
|
+
end
|
90
|
+
|
91
|
+
destroyed
|
92
|
+
end
|
93
|
+
|
94
|
+
# Given a string queue name, returns an instance of Resque::Job
|
95
|
+
# if any jobs are available. If not, returns nil.
|
96
|
+
def self.reserve(queue)
|
97
|
+
return unless payload = Resque.pop(queue)
|
98
|
+
new(queue, payload)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Attempts to perform the work represented by this job instance.
|
102
|
+
# Calls #perform on the class given in the payload with the
|
103
|
+
# arguments given in the payload.
|
104
|
+
def perform
|
105
|
+
job = payload_class
|
106
|
+
job_args = args || []
|
107
|
+
job_was_performed = false
|
108
|
+
|
109
|
+
begin
|
110
|
+
# Execute before_perform hook. Abort the job gracefully if
|
111
|
+
# Resque::DontPerform is raised.
|
112
|
+
begin
|
113
|
+
before_hooks.each do |hook|
|
114
|
+
job.send(hook, *job_args)
|
115
|
+
end
|
116
|
+
rescue DontPerform
|
117
|
+
return false
|
118
|
+
end
|
119
|
+
|
120
|
+
# Execute the job. Do it in an around_perform hook if available.
|
121
|
+
if around_hooks.empty?
|
122
|
+
job.perform(*job_args)
|
123
|
+
job_was_performed = true
|
124
|
+
else
|
125
|
+
# We want to nest all around_perform plugins, with the last one
|
126
|
+
# finally calling perform
|
127
|
+
stack = around_hooks.reverse.inject(nil) do |last_hook, hook|
|
128
|
+
if last_hook
|
129
|
+
lambda do
|
130
|
+
job.send(hook, *job_args) { last_hook.call }
|
131
|
+
end
|
132
|
+
else
|
133
|
+
lambda do
|
134
|
+
job.send(hook, *job_args) do
|
135
|
+
result = job.perform(*job_args)
|
136
|
+
job_was_performed = true
|
137
|
+
result
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
stack.call
|
143
|
+
end
|
144
|
+
|
145
|
+
# Execute after_perform hook
|
146
|
+
after_hooks.each do |hook|
|
147
|
+
job.send(hook, *job_args)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Return true if the job was performed
|
151
|
+
return job_was_performed
|
152
|
+
|
153
|
+
# If an exception occurs during the job execution, look for an
|
154
|
+
# on_failure hook then re-raise.
|
155
|
+
rescue Object => e
|
156
|
+
run_failure_hooks(e)
|
157
|
+
raise e
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# Returns the actual class constant represented in this job's payload.
|
162
|
+
def payload_class
|
163
|
+
@payload_class ||= constantize(@payload['class'])
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns an array of args represented in this job's payload.
|
167
|
+
def args
|
168
|
+
@payload['args']
|
169
|
+
end
|
170
|
+
|
171
|
+
# Given an exception object, hands off the needed parameters to
|
172
|
+
# the Failure module.
|
173
|
+
def fail(exception)
|
174
|
+
run_failure_hooks(exception)
|
175
|
+
Failure.create \
|
176
|
+
:payload => payload,
|
177
|
+
:exception => exception,
|
178
|
+
:worker => worker,
|
179
|
+
:queue => queue
|
180
|
+
end
|
181
|
+
|
182
|
+
# Creates an identical job, essentially placing this job back on
|
183
|
+
# the queue.
|
184
|
+
def recreate
|
185
|
+
self.class.create(queue, payload_class, *args)
|
186
|
+
end
|
187
|
+
|
188
|
+
# String representation
|
189
|
+
def inspect
|
190
|
+
obj = @payload
|
191
|
+
"(Job{%s} | %s | %s)" % [ @queue, obj['class'], obj['args'].inspect ]
|
192
|
+
end
|
193
|
+
|
194
|
+
# Equality
|
195
|
+
def ==(other)
|
196
|
+
queue == other.queue &&
|
197
|
+
payload_class == other.payload_class &&
|
198
|
+
args == other.args
|
199
|
+
end
|
200
|
+
|
201
|
+
def before_hooks
|
202
|
+
@before_hooks ||= Plugin.before_hooks(payload_class)
|
203
|
+
end
|
204
|
+
|
205
|
+
def around_hooks
|
206
|
+
@around_hooks ||= Plugin.around_hooks(payload_class)
|
207
|
+
end
|
208
|
+
|
209
|
+
def after_hooks
|
210
|
+
@after_hooks ||= Plugin.after_hooks(payload_class)
|
211
|
+
end
|
212
|
+
|
213
|
+
def failure_hooks
|
214
|
+
@failure_hooks ||= Plugin.failure_hooks(payload_class)
|
215
|
+
end
|
216
|
+
|
217
|
+
def run_failure_hooks(exception)
|
218
|
+
job_args = args || []
|
219
|
+
failure_hooks.each { |hook| payload_class.send(hook, exception, *job_args) }
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'resque/coder'
|
3
|
+
|
4
|
+
# OkJson won't work because it doesn't serialize symbols
|
5
|
+
# in the same way yajl and json do.
|
6
|
+
|
7
|
+
if MultiJson.respond_to?(:adapter)
|
8
|
+
raise "Please install the yajl-ruby or json gem" if MultiJson.adapter.to_s == 'MultiJson::Adapters::OkJson'
|
9
|
+
elsif MultiJson.respond_to?(:engine)
|
10
|
+
raise "Please install the yajl-ruby or json gem" if MultiJson.engine.to_s == 'MultiJson::Engines::OkJson'
|
11
|
+
end
|
12
|
+
|
13
|
+
module Resque
|
14
|
+
class MultiJsonCoder < Coder
|
15
|
+
def encode(object)
|
16
|
+
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
17
|
+
MultiJson.dump object
|
18
|
+
else
|
19
|
+
MultiJson.encode object
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def decode(object)
|
24
|
+
return unless object
|
25
|
+
|
26
|
+
begin
|
27
|
+
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
28
|
+
MultiJson.load object
|
29
|
+
else
|
30
|
+
MultiJson.decode object
|
31
|
+
end
|
32
|
+
rescue ::MultiJson::DecodeError => e
|
33
|
+
raise DecodeException, e.message, e.backtrace
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'redis-namespace'
|
3
|
+
require 'thread'
|
4
|
+
require 'mutex_m'
|
5
|
+
|
6
|
+
module Resque
|
7
|
+
###
|
8
|
+
# Holds multiple queues, allowing you to pop the first available job
|
9
|
+
class MultiQueue
|
10
|
+
include Mutex_m
|
11
|
+
|
12
|
+
###
|
13
|
+
# Create a new MultiQueue using the +queues+ from the +redis+ connection
|
14
|
+
def initialize(queues, redis)
|
15
|
+
super()
|
16
|
+
|
17
|
+
@queues = queues # since ruby 1.8 doesn't have Ordered Hashes
|
18
|
+
@queue_hash = {}
|
19
|
+
@redis = redis
|
20
|
+
|
21
|
+
queues.each do |queue|
|
22
|
+
key = @redis.is_a?(Redis::Namespace) ? "#{@redis.namespace}:" : ""
|
23
|
+
key += queue.redis_name
|
24
|
+
@queue_hash[key] = queue
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Pop an item off one of the queues. This method will block until an item
|
29
|
+
# is available. This method returns a tuple of the queue object and job.
|
30
|
+
#
|
31
|
+
# Pass +true+ for a non-blocking pop. If nothing is read on a non-blocking
|
32
|
+
# pop, a ThreadError is raised.
|
33
|
+
def pop(non_block = false)
|
34
|
+
if non_block
|
35
|
+
synchronize do
|
36
|
+
value = nil
|
37
|
+
|
38
|
+
@queues.each do |queue|
|
39
|
+
begin
|
40
|
+
return [queue, queue.pop(true)]
|
41
|
+
rescue ThreadError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
raise ThreadError
|
46
|
+
end
|
47
|
+
else
|
48
|
+
queue_names = @queues.map {|queue| queue.redis_name }
|
49
|
+
synchronize do
|
50
|
+
value = @redis.blpop(*(queue_names + [1])) until value
|
51
|
+
queue_name, payload = value
|
52
|
+
queue = @queue_hash[queue_name]
|
53
|
+
[queue, queue.decode(payload)]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Retrieves data from the queue head, and removes it.
|
59
|
+
#
|
60
|
+
# Blocks for +timeout+ seconds if the queue is empty, and returns nil if
|
61
|
+
# the timeout expires.
|
62
|
+
def poll(timeout)
|
63
|
+
queue_names = @queues.map {|queue| queue.redis_name }
|
64
|
+
queue_name, payload = @redis.blpop(*(queue_names + [timeout]))
|
65
|
+
return unless payload
|
66
|
+
|
67
|
+
synchronize do
|
68
|
+
queue = @queue_hash[queue_name]
|
69
|
+
[queue, queue.decode(payload)]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Resque
|
2
|
+
module Plugin
|
3
|
+
extend self
|
4
|
+
|
5
|
+
LintError = Class.new(RuntimeError)
|
6
|
+
|
7
|
+
# Ensure that your plugin conforms to good hook naming conventions.
|
8
|
+
#
|
9
|
+
# Resque::Plugin.lint(MyResquePlugin)
|
10
|
+
def lint(plugin)
|
11
|
+
hooks = before_hooks(plugin) + around_hooks(plugin) + after_hooks(plugin)
|
12
|
+
|
13
|
+
hooks.each do |hook|
|
14
|
+
if hook =~ /perform$/
|
15
|
+
raise LintError, "#{plugin}.#{hook} is not namespaced"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
failure_hooks(plugin).each do |hook|
|
20
|
+
if hook =~ /failure$/
|
21
|
+
raise LintError, "#{plugin}.#{hook} is not namespaced"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Given an object, returns a list `before_perform` hook names.
|
27
|
+
def before_hooks(job)
|
28
|
+
job.methods.grep(/^before_perform/).sort
|
29
|
+
end
|
30
|
+
|
31
|
+
# Given an object, returns a list `around_perform` hook names.
|
32
|
+
def around_hooks(job)
|
33
|
+
job.methods.grep(/^around_perform/).sort
|
34
|
+
end
|
35
|
+
|
36
|
+
# Given an object, returns a list `after_perform` hook names.
|
37
|
+
def after_hooks(job)
|
38
|
+
job.methods.grep(/^after_perform/).sort
|
39
|
+
end
|
40
|
+
|
41
|
+
# Given an object, returns a list `on_failure` hook names.
|
42
|
+
def failure_hooks(job)
|
43
|
+
job.methods.grep(/^on_failure/).sort
|
44
|
+
end
|
45
|
+
|
46
|
+
# Given an object, returns a list `after_enqueue` hook names.
|
47
|
+
def after_enqueue_hooks(job)
|
48
|
+
job.methods.grep(/^after_enqueue/).sort
|
49
|
+
end
|
50
|
+
|
51
|
+
# Given an object, returns a list `before_enqueue` hook names.
|
52
|
+
def before_enqueue_hooks(job)
|
53
|
+
job.methods.grep(/^before_enqueue/).sort
|
54
|
+
end
|
55
|
+
|
56
|
+
# Given an object, returns a list `after_dequeue` hook names.
|
57
|
+
def after_dequeue_hooks(job)
|
58
|
+
job.methods.grep(/^after_dequeue/).sort
|
59
|
+
end
|
60
|
+
|
61
|
+
# Given an object, returns a list `before_dequeue` hook names.
|
62
|
+
def before_dequeue_hooks(job)
|
63
|
+
job.methods.grep(/^before_dequeue/).sort
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/resque/queue.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'redis-namespace'
|
3
|
+
require 'thread'
|
4
|
+
require 'mutex_m'
|
5
|
+
|
6
|
+
module Resque
|
7
|
+
###
|
8
|
+
# Exception raised when trying to access a queue that's already destroyed
|
9
|
+
class QueueDestroyed < RuntimeError; end
|
10
|
+
|
11
|
+
###
|
12
|
+
# A queue interface that quacks like Queue from Ruby's stdlib.
|
13
|
+
class Queue
|
14
|
+
include Mutex_m
|
15
|
+
|
16
|
+
attr_reader :name, :redis_name
|
17
|
+
|
18
|
+
###
|
19
|
+
# Create a new Queue object with +name+ on +redis+ connection, and using
|
20
|
+
# the +coder+ for encoding and decoding objects that are stored in redis.
|
21
|
+
def initialize name, redis, coder = Marshal
|
22
|
+
super()
|
23
|
+
@name = name
|
24
|
+
@redis_name = "queue:#{@name}"
|
25
|
+
@redis = redis
|
26
|
+
@coder = coder
|
27
|
+
@destroyed = false
|
28
|
+
|
29
|
+
@redis.sadd(:queues, @name)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Add +object+ to the queue
|
33
|
+
# If trying to push to an already destroyed queue, it will raise a Resque::QueueDestroyed exception
|
34
|
+
def push object
|
35
|
+
raise QueueDestroyed if destroyed?
|
36
|
+
|
37
|
+
synchronize do
|
38
|
+
@redis.rpush @redis_name, encode(object)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
alias :<< :push
|
43
|
+
alias :enq :push
|
44
|
+
|
45
|
+
# Returns a list of objects in the queue. This method is *not* available
|
46
|
+
# on the stdlib Queue.
|
47
|
+
def slice start, length
|
48
|
+
if length == 1
|
49
|
+
synchronize do
|
50
|
+
decode @redis.lindex @redis_name, start
|
51
|
+
end
|
52
|
+
else
|
53
|
+
synchronize do
|
54
|
+
Array(@redis.lrange(@redis_name, start, start + length - 1)).map do |item|
|
55
|
+
decode item
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Pop an item off the queue. This method will block until an item is
|
62
|
+
# available.
|
63
|
+
#
|
64
|
+
# Pass +true+ for a non-blocking pop. If nothing is read on a non-blocking
|
65
|
+
# pop, a ThreadError is raised.
|
66
|
+
def pop non_block = false
|
67
|
+
if non_block
|
68
|
+
synchronize do
|
69
|
+
value = @redis.lpop(@redis_name)
|
70
|
+
raise ThreadError unless value
|
71
|
+
decode value
|
72
|
+
end
|
73
|
+
else
|
74
|
+
synchronize do
|
75
|
+
value = @redis.blpop(@redis_name, 1) until value
|
76
|
+
decode value.last
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get the length of the queue
|
82
|
+
def length
|
83
|
+
@redis.llen @redis_name
|
84
|
+
end
|
85
|
+
alias :size :length
|
86
|
+
|
87
|
+
# Is the queue empty?
|
88
|
+
def empty?
|
89
|
+
size == 0
|
90
|
+
end
|
91
|
+
|
92
|
+
# Deletes this Queue from redis. This method is *not* available on the
|
93
|
+
# stdlib Queue.
|
94
|
+
#
|
95
|
+
# If there are multiple queue objects of the same name, Queue A and Queue
|
96
|
+
# B and you delete Queue A, pushing to Queue B will have unknown side
|
97
|
+
# effects. Queue A will be marked destroyed, but Queue B will not.
|
98
|
+
def destroy
|
99
|
+
@redis.del @redis_name
|
100
|
+
@redis.srem(:queues, @name)
|
101
|
+
@destroyed = true
|
102
|
+
end
|
103
|
+
|
104
|
+
# returns +true+ if the queue is destroyed and +false+ if it isn't
|
105
|
+
def destroyed?
|
106
|
+
@destroyed
|
107
|
+
end
|
108
|
+
|
109
|
+
def encode object
|
110
|
+
@coder.dump object
|
111
|
+
end
|
112
|
+
|
113
|
+
def decode object
|
114
|
+
@coder.load object
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|