remq-rb 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/LICENSE +7 -0
- data/README.md +51 -0
- data/Rakefile +92 -0
- data/lib/ReMQ.rb +69 -0
- data/lib/ReMQ/Queue.rb +29 -0
- data/lib/ReMQ/Worker.rb +87 -0
- data/remq-rb.gemspec +40 -0
- data/test/helper.rb +46 -0
- data/test/queue_test.rb +25 -0
- data/test/worker_test.rb +63 -0
- metadata +121 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2012 Matthew Loberg
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# ReMQ.rb
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/mloberg/ReMQ.rb.png?branch=master)](https://travis-ci.org/mloberg/ReMQ.rb)
|
4
|
+
|
5
|
+
Redis Message Queue (ReMQ) is a message queue built on top of the awesome Redis key-value store.
|
6
|
+
|
7
|
+
This is the Ruby clone of the original [ReMQ](https://github.com/mloberg/ReMQ) PHP library.
|
8
|
+
|
9
|
+
## Getting ReMQ
|
10
|
+
|
11
|
+
coming soon
|
12
|
+
|
13
|
+
## Jobs
|
14
|
+
|
15
|
+
Jobs are stored as classes. The class must have a perform method which can take a variable number of parameters/
|
16
|
+
|
17
|
+
class Job
|
18
|
+
|
19
|
+
def self.perform(param1, param2)
|
20
|
+
puts "Ran job with #{param1} and #{param2}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
## Queuing Jobs
|
26
|
+
|
27
|
+
Instead of creating a queue for each job, ReMQ allows multiple jobs per queue. This is for simplicity's sake, and there is no other reason behind it.
|
28
|
+
|
29
|
+
queue = ReMQ::Queue.new('name')
|
30
|
+
queue.enqueue(Job, 'param1', 'param2')
|
31
|
+
|
32
|
+
## Processing Jobs
|
33
|
+
|
34
|
+
To process a job, you need to create a worker for the queue.
|
35
|
+
|
36
|
+
worker = ReMQ::Worker.new('name')
|
37
|
+
|
38
|
+
You can also add additional queues to the process.
|
39
|
+
|
40
|
+
worker.add_queue('other')
|
41
|
+
|
42
|
+
You can also match queue names.
|
43
|
+
|
44
|
+
worker.add_queue('*')
|
45
|
+
worker.add_queue('namespaced:*')
|
46
|
+
|
47
|
+
Running the worker.
|
48
|
+
|
49
|
+
worker.run(:time => 60)
|
50
|
+
worker.run(:count => 10)
|
51
|
+
worker.run()
|
data/Rakefile
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require "date"
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
4
|
+
|
5
|
+
require "ReMQ"
|
6
|
+
|
7
|
+
##
|
8
|
+
# Helper functions
|
9
|
+
##
|
10
|
+
|
11
|
+
def name
|
12
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
13
|
+
end
|
14
|
+
|
15
|
+
def version
|
16
|
+
ReMQ::VERSION
|
17
|
+
end
|
18
|
+
|
19
|
+
def date
|
20
|
+
Date.today.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def gemspec_file
|
24
|
+
"#{name}.gemspec"
|
25
|
+
end
|
26
|
+
|
27
|
+
def gem_file
|
28
|
+
"#{name}-#{version}.gem"
|
29
|
+
end
|
30
|
+
|
31
|
+
def replace_header(head, header_name)
|
32
|
+
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
33
|
+
end
|
34
|
+
|
35
|
+
task :default => [:test]
|
36
|
+
|
37
|
+
require 'rake/testtask'
|
38
|
+
Rake::TestTask.new do |t|
|
39
|
+
t.libs = ["lib", "test"]
|
40
|
+
t.warning = true
|
41
|
+
t.warning = true
|
42
|
+
t.test_files = FileList['test/*_test.rb']
|
43
|
+
end
|
44
|
+
|
45
|
+
task :doc do
|
46
|
+
sh "yardoc"
|
47
|
+
end
|
48
|
+
|
49
|
+
###
|
50
|
+
# Packing tasks
|
51
|
+
###
|
52
|
+
|
53
|
+
desc "Build gem"
|
54
|
+
task :build do
|
55
|
+
FileUtils.mkdir_p "pkg"
|
56
|
+
system "gem build #{gemspec_file}"
|
57
|
+
FileUtils.mv gem_file, "pkg"
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Install gem locally"
|
61
|
+
task :install => :build do
|
62
|
+
system "gem install pkg/#{gem_file}"
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Clean automatically generated files"
|
66
|
+
task :clean do
|
67
|
+
FileUtils.rm_rf "pkg"
|
68
|
+
FileUtils.rm_rf ".yardoc"
|
69
|
+
FileUtils.rm_rf "doc"
|
70
|
+
end
|
71
|
+
|
72
|
+
task :gemspec do
|
73
|
+
spec = File.read(gemspec_file)
|
74
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
75
|
+
|
76
|
+
replace_header(head, :name)
|
77
|
+
replace_header(head, :version)
|
78
|
+
replace_header(head, :date)
|
79
|
+
|
80
|
+
files = `git ls-files`.
|
81
|
+
split("\n").
|
82
|
+
sort.
|
83
|
+
reject { |file| file =~ /^\./ }.
|
84
|
+
reject { |file| file =~ /^(pkg)/ }.
|
85
|
+
map { |file| " #{file}"}.
|
86
|
+
join("\n")
|
87
|
+
|
88
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
89
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
90
|
+
File.open(gemspec_file, 'w') { |f| f.write(spec) }
|
91
|
+
puts "Updated #{gemspec_file}"
|
92
|
+
end
|
data/lib/ReMQ.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require "redis"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
require "ReMQ/Queue"
|
7
|
+
require "ReMQ/Worker"
|
8
|
+
|
9
|
+
module ReMQ
|
10
|
+
VERSION = '0.0.2'
|
11
|
+
|
12
|
+
class BadJobError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
extend self
|
16
|
+
|
17
|
+
# Get a normalized ReMQ queue name.
|
18
|
+
#
|
19
|
+
# @param [String] name
|
20
|
+
# @return [String]
|
21
|
+
def normalize_queue_name(name)
|
22
|
+
"remq:#{name}"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set Redis connection options.
|
26
|
+
#
|
27
|
+
# @param [Hash] config
|
28
|
+
def set_redis_config(config)
|
29
|
+
@redis = Redis.new(config)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Set a custom Redis connection.
|
33
|
+
#
|
34
|
+
# @param [Object] redis
|
35
|
+
def set_redis(redis)
|
36
|
+
@redis = redis
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return the Redis connection or create a new connection.
|
40
|
+
#
|
41
|
+
# @return [Object] Redis conenction
|
42
|
+
def redis
|
43
|
+
@redis ||= Redis.new
|
44
|
+
end
|
45
|
+
|
46
|
+
# Check if the job is a valid job.
|
47
|
+
#
|
48
|
+
# @raise [ReMQ::BadJobError]
|
49
|
+
# @param [Object] job
|
50
|
+
# @return [Boolean]
|
51
|
+
def is_valid_job?(job)
|
52
|
+
# check if is class
|
53
|
+
if job.class != Class and Object.const_defined?(job)
|
54
|
+
job = Object.const_get(job)
|
55
|
+
elsif job.class != Class
|
56
|
+
raise BadJobError, "#{job} is not a class"
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
# Ruby 1.9 uses a symbol for methods, while 1.8 uses strings
|
60
|
+
method = RUBY_VERSION.gsub(/\.\d$/, '') == '1.9' ? :perform : 'perform'
|
61
|
+
# check if it has the perform method
|
62
|
+
unless job.methods.include?(method)
|
63
|
+
raise BadJobError, "#{job} does not have a perform method"
|
64
|
+
return false
|
65
|
+
end
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/lib/ReMQ/Queue.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module ReMQ
|
2
|
+
class Queue
|
3
|
+
|
4
|
+
# @!attribute [r] name
|
5
|
+
# @return [String] the queue name
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
# Create a new queue.
|
9
|
+
#
|
10
|
+
# @param [String] name queue name
|
11
|
+
def initialize(name)
|
12
|
+
@name = ReMQ.normalize_queue_name(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Add a job to the queue.
|
16
|
+
#
|
17
|
+
# @raise [ReMQ::BadJobError] if job is invalid
|
18
|
+
# @param [String] class Job class name
|
19
|
+
# @param [mixed] params Job parameters
|
20
|
+
# @return [Boolean] true if job was queued
|
21
|
+
def enqueue(*args)
|
22
|
+
body = args.to_json
|
23
|
+
if ReMQ.is_valid_job?(args.first)
|
24
|
+
ReMQ.redis().rpush(name, body)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/ReMQ/Worker.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
module ReMQ
|
2
|
+
class Worker
|
3
|
+
|
4
|
+
# Create a new ReMQ worker.
|
5
|
+
#
|
6
|
+
# @param [String] name Optional name of the queue
|
7
|
+
def initialize(name = nil)
|
8
|
+
@queues = []
|
9
|
+
add_queue(name) if name
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return the list of quques that this worker will run.
|
13
|
+
#
|
14
|
+
# @return [Array] Array of queues
|
15
|
+
def queues
|
16
|
+
@queues.map { |name| name.gsub(/^remq\:/, '') }
|
17
|
+
end
|
18
|
+
|
19
|
+
# Add a queue to the worker.
|
20
|
+
#
|
21
|
+
# @param [String] name Queue name
|
22
|
+
def add_queue(name)
|
23
|
+
queues = find_queues(name)
|
24
|
+
queues << ReMQ.normalize_queue_name(name)
|
25
|
+
@queues = @queues.concat(queues).uniq
|
26
|
+
end
|
27
|
+
|
28
|
+
# Remove a queue from the worker.
|
29
|
+
#
|
30
|
+
# @param [String] name Queue name
|
31
|
+
def remove_queue(name)
|
32
|
+
@queues.delete(ReMQ.normalize_queue_name(name))
|
33
|
+
end
|
34
|
+
|
35
|
+
# Run the worker
|
36
|
+
#
|
37
|
+
# @param [Integer] time Seconds to run the worker for
|
38
|
+
# @param [Integer] count Number of jobs to run
|
39
|
+
def run(args = {})
|
40
|
+
if args[:time]
|
41
|
+
start = Time.now
|
42
|
+
while (start + args[:time]) > Time.now do
|
43
|
+
process(1)
|
44
|
+
end
|
45
|
+
elsif args[:count]
|
46
|
+
args[:count].times do
|
47
|
+
process(0)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
loop do
|
51
|
+
process(0)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Find queues in Redis
|
59
|
+
#
|
60
|
+
# @param [String] match
|
61
|
+
def find_queues(match)
|
62
|
+
match = ReMQ.normalize_queue_name(match)
|
63
|
+
ReMQ.redis.keys(match)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Handle the job processing
|
67
|
+
#
|
68
|
+
# @param [Integer] timeout Redis BLPOP timeout
|
69
|
+
def process(timeout)
|
70
|
+
queues = @queues << timeout
|
71
|
+
begin
|
72
|
+
queue, job = ReMQ.redis.blpop(*queues)
|
73
|
+
if job
|
74
|
+
body = JSON.parse(job)
|
75
|
+
job_class = body.shift
|
76
|
+
if ReMQ.is_valid_job?(job_class)
|
77
|
+
Object.const_get(job_class).perform(*body)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
rescue Exception => e
|
81
|
+
ReMQ.redis.rpush(queue, job)
|
82
|
+
raise e
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/remq-rb.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
2
|
+
|
3
|
+
line = File.read("lib/ReMQ.rb")[/^\s*VERSION\s*=\s*.*/]
|
4
|
+
version = line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'remq-rb'
|
8
|
+
s.version = version
|
9
|
+
s.summary = "Redis based message queue."
|
10
|
+
s.description = "Redis Message Queue (ReMQ) is a message queue backed by the awesome key-value store, Redis."
|
11
|
+
s.homepage = 'https://github.com/mloberg/ReMQ.rb'
|
12
|
+
s.authors = ["Matthew Loberg"]
|
13
|
+
s.email = 'm@mloberg.com'
|
14
|
+
|
15
|
+
s.require_paths = %w[lib]
|
16
|
+
|
17
|
+
s.add_runtime_dependency('redis', "~> 3.0")
|
18
|
+
s.add_runtime_dependency('json', "~> 1.7")
|
19
|
+
|
20
|
+
s.add_development_dependency('rake', "~> 0.9")
|
21
|
+
s.add_development_dependency('yard', "~> 0.8")
|
22
|
+
|
23
|
+
# = MANIFEST =
|
24
|
+
s.files = %w[
|
25
|
+
Gemfile
|
26
|
+
LICENSE
|
27
|
+
README.md
|
28
|
+
Rakefile
|
29
|
+
lib/ReMQ.rb
|
30
|
+
lib/ReMQ/Queue.rb
|
31
|
+
lib/ReMQ/Worker.rb
|
32
|
+
remq-rb.gemspec
|
33
|
+
test/helper.rb
|
34
|
+
test/queue_test.rb
|
35
|
+
test/worker_test.rb
|
36
|
+
]
|
37
|
+
# = MANIFEST =
|
38
|
+
|
39
|
+
s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
|
40
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
require "ReMQ"
|
4
|
+
|
5
|
+
module Test::Unit::Assertions
|
6
|
+
|
7
|
+
def assert_contains(needle, haystack, msg = nil)
|
8
|
+
unless msg
|
9
|
+
msg = "#{haystack} was expected to contain #{needle}"
|
10
|
+
end
|
11
|
+
assert(haystack.include?(needle), msg)
|
12
|
+
end
|
13
|
+
|
14
|
+
def assert_not_contains(needle, haystack, msg = nil)
|
15
|
+
unless msg
|
16
|
+
msg = "#{haystack} was expected to not contain #{needle}"
|
17
|
+
end
|
18
|
+
assert(!haystack.include?(needle), msg)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
class TestJob
|
24
|
+
|
25
|
+
extend Test::Unit::Assertions
|
26
|
+
|
27
|
+
def self.perform(foo, bar)
|
28
|
+
assert_equal(foo, 'foo')
|
29
|
+
assert_equal(bar, 'bar')
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class FailingJobError < StandardError
|
35
|
+
end
|
36
|
+
|
37
|
+
class FailingJob
|
38
|
+
|
39
|
+
def self.perform
|
40
|
+
raise FailingJobError, "did not run job"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class BadJob
|
46
|
+
end
|
data/test/queue_test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class TestQueue < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@redis_mock = Object.new
|
7
|
+
@redis_mock.extend(Test::Unit::Assertions)
|
8
|
+
ReMQ.set_redis(@redis_mock)
|
9
|
+
@queue = ReMQ::Queue.new('test')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_enqueue
|
13
|
+
def @redis_mock.rpush(key, value)
|
14
|
+
assert_equal('remq:test', key)
|
15
|
+
assert_equal(['TestJob', 'foo', 'bar'].to_json, value)
|
16
|
+
return true
|
17
|
+
end
|
18
|
+
assert(@queue.enqueue(TestJob, 'foo', 'bar'))
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_throws_error_on_bad_job
|
22
|
+
assert_raise(ReMQ::BadJobError) { @queue.enqueue(BadJob) }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/test/worker_test.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class TestWorker < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@redis_mock = Object.new
|
7
|
+
@redis_mock.extend(Test::Unit::Assertions)
|
8
|
+
ReMQ.set_redis(@redis_mock)
|
9
|
+
@worker = ReMQ::Worker.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def redis_keys_returns_empty
|
13
|
+
def @redis_mock.keys(match)
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_add_queue
|
19
|
+
redis_keys_returns_empty
|
20
|
+
@worker.add_queue('example')
|
21
|
+
assert_contains('example', @worker.queues)
|
22
|
+
@worker.add_queue('test')
|
23
|
+
assert_contains('test', @worker.queues)
|
24
|
+
# assert that the previous queue is still in place
|
25
|
+
assert_contains('test', @worker.queues)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_remove_queue
|
29
|
+
redis_keys_returns_empty
|
30
|
+
@worker.add_queue('example')
|
31
|
+
@worker.add_queue('test')
|
32
|
+
@worker.remove_queue('example')
|
33
|
+
assert_not_contains('example', @worker.queues)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_process
|
37
|
+
def @redis_mock.blpop(*args)
|
38
|
+
[ 'example', [ 'TestJob', 'foo', 'bar' ].to_json ]
|
39
|
+
end
|
40
|
+
@worker.run(:count => 1)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_reenqueue_after_exception
|
44
|
+
def @redis_mock.rpush(key, value)
|
45
|
+
assert_equal('example', key)
|
46
|
+
assert_equal(['FailingJob'].to_json, value)
|
47
|
+
end
|
48
|
+
def @redis_mock.blpop(*args)
|
49
|
+
[ 'example', [ 'FailingJob' ].to_json ]
|
50
|
+
end
|
51
|
+
assert_raise(FailingJobError) { @worker.run(:count => 1) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_throws_exception_if_not_valid_job
|
55
|
+
def @redis_mock.blpop(*args)
|
56
|
+
[ 'example', [ 'BadJob' ].to_json ]
|
57
|
+
end
|
58
|
+
def @redis_mock.rpush(key, value)
|
59
|
+
end
|
60
|
+
assert_raise(ReMQ::BadJobError) { @worker.run(:count => 1) }
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: remq-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matthew Loberg
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: redis
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.7'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.7'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.9'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.9'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: yard
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.8'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.8'
|
78
|
+
description: Redis Message Queue (ReMQ) is a message queue backed by the awesome key-value
|
79
|
+
store, Redis.
|
80
|
+
email: m@mloberg.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- Gemfile
|
86
|
+
- LICENSE
|
87
|
+
- README.md
|
88
|
+
- Rakefile
|
89
|
+
- lib/ReMQ.rb
|
90
|
+
- lib/ReMQ/Queue.rb
|
91
|
+
- lib/ReMQ/Worker.rb
|
92
|
+
- remq-rb.gemspec
|
93
|
+
- test/helper.rb
|
94
|
+
- test/queue_test.rb
|
95
|
+
- test/worker_test.rb
|
96
|
+
homepage: https://github.com/mloberg/ReMQ.rb
|
97
|
+
licenses: []
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 1.8.24
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: Redis based message queue.
|
120
|
+
test_files: []
|
121
|
+
has_rdoc:
|