line_up 0.0.2
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/LICENSE +21 -0
- data/README.md +55 -0
- data/lib/line_up/configuration.rb +49 -0
- data/lib/line_up/job.rb +23 -0
- data/lib/line_up/string_extensions.rb +16 -0
- data/lib/line_up/version.rb +9 -0
- data/lib/line_up.rb +38 -0
- data/spec/lib/line_up_spec.rb +106 -0
- data/spec/spec_helper.rb +40 -0
- metadata +154 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2013 Bukowskis
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# LineUp
|
2
|
+
|
3
|
+
With LineUp you can enqueue Resque jobs in arbitrary Redis namespaces.
|
4
|
+
|
5
|
+
[Resque](https://github.com/defunkt/resque) uses a [Set](http://redis.io/commands#set) and a [List](http://redis.io/commands#list) to keep track of all Queues and their Jobs.
|
6
|
+
|
7
|
+
* The Set is usually located at `resque:queues` and contains a list of (lower-cased, underscored) Strings, each representing a queue name
|
8
|
+
* Each queue is a List located at `resque:queue:my_job` (with `my_job` as queue name for `MyJob`-jobs in this example)
|
9
|
+
* Each job inside of a queue is a JSON or Marshal'ed Hash with the keys `class` and `args`, for example `{ class: 'MyJob', args: [123, some: thing] }.to_json`
|
10
|
+
|
11
|
+
Depending on how you configure the Redis backend for Resque, you will end up in a different namespace:
|
12
|
+
|
13
|
+
* If you use `Resque.redis = Redis::Namespace.new(:bob, ...)`, Resque [detects](https://github.com/defunkt/resque/blob/master/lib/resque.rb#L55) that you passed in an `Redis::Namespace` object and will __not__ add any additional namespace. So the queue Set in this example will be located at `bob:queues`
|
14
|
+
* Any other `Redis.new`-compatible object will get the `resque`-namespace added. So `Resque.redis = Redis.new(...)` will cause the queue Set to be located at `resque:queues`
|
15
|
+
|
16
|
+
If you use multiple applications, you should make sure that each of them has its own namespace. You would normally achieve that with `Resque.redis = Redis::Namespace.new('myapp:resque', ...)` so that the queue Set would be located at `myapp:resque:queues`.
|
17
|
+
|
18
|
+
So far so good, __but__ there is no way to enqueue a Job for an application from inside another namespace, say `otherapp:resque:queues`, without maintaining an additional connection to Redis in the other app's namespace. So far, the only solution has been to share the `resque:queues` namespace between all applications and have separate queue-names, such as `myapp-myjob` and `otherapp-myjob`, but that is not really separating namespaces.
|
19
|
+
|
20
|
+
That's where LineUp comes in, it doesn't even need Resque. It goes right into Redis (scary huh?), just as Resque does [internally](https://github.com/defunkt/resque/blob/master/lib/resque/queue.rb).
|
21
|
+
|
22
|
+
# Examples
|
23
|
+
|
24
|
+
### Setup
|
25
|
+
|
26
|
+
If you use the `Raidis` gem, you _do not need_ any setup. Otherwise, a manual setup would look like this:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
redis = Redis::Namespace.new 'myapp:resque', redis: Redis.new(...)
|
30
|
+
|
31
|
+
Resque.redis = redis
|
32
|
+
LineUp.redis = redis
|
33
|
+
````
|
34
|
+
|
35
|
+
### Usage
|
36
|
+
|
37
|
+
With the setup above, Resque lies in the `myapp:resque`-namespace. So you can enqeueue jobs to the very same application by using `Resque.enqueue(...)`.
|
38
|
+
|
39
|
+
This is how you can enqueue a job for another applications:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
if LineUp.push :otherApp, :SomeJob, 12345, some: thing
|
43
|
+
# Yey, everything went well
|
44
|
+
else
|
45
|
+
# The "Trouble"-gem, has been notified and I can process the failure if I like
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
This will enqueue to `other_app:resque:some_job` with arguments `[12345, { 'some' => 'thing' }]` and make sure that the `other_app:resque:queues` Set references the queue List.
|
50
|
+
|
51
|
+
# Gotchas
|
52
|
+
|
53
|
+
* `Resque.redis` MUST respond to a method called `#namespace` which takes a block and yields a new namespace. See [this commit](https://github.com/defunkt/redis-namespace/pull/50). Currently LineUp [requires a non-rubygems fork](https://github.com/bukowskis/line_up/blob/master/Gemfile) of `Redis::Namespace` in order to be able to use this cutting-edge method.
|
54
|
+
* Currently the jobs are encoded using `MultiJson` only, not `Marshal`, feel free to commit a patch if you need the latter
|
55
|
+
* You cannot share the `resque` root namespace. LineUp defaults to the `application:resque` namespace (because that's the only scenario I can think of that would make you want to use LineUp in the first place :)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module LineUp
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :logger, :redis
|
6
|
+
|
7
|
+
def initialize(options={})
|
8
|
+
@logger = options[:logger] || default_logger
|
9
|
+
@redis = options[:redis] || default_redis
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def default_logger
|
15
|
+
if defined?(Rails)
|
16
|
+
Rails.logger
|
17
|
+
else
|
18
|
+
Logger.new(STDOUT)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_redis
|
23
|
+
return Raidis.redis if defined?(Raidis)
|
24
|
+
return Resque.redis if defined?(Resque)
|
25
|
+
Redis::Namespace.new nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module LineUp
|
31
|
+
|
32
|
+
# Public: Returns the the Configuration instance.
|
33
|
+
#
|
34
|
+
def self.config
|
35
|
+
@config ||= Configuration.new
|
36
|
+
end
|
37
|
+
|
38
|
+
# Public: Yields the Configuration instance.
|
39
|
+
#
|
40
|
+
def self.configure(&block)
|
41
|
+
yield config
|
42
|
+
end
|
43
|
+
|
44
|
+
# Public: Reset the Configuration (useful for testing)
|
45
|
+
#
|
46
|
+
def self.reset!
|
47
|
+
@config = nil
|
48
|
+
end
|
49
|
+
end
|
data/lib/line_up/job.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'line_up/string_extensions'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module LineUp
|
5
|
+
class Job
|
6
|
+
|
7
|
+
attr_reader :klass, :args
|
8
|
+
|
9
|
+
def initialize(klass, *args)
|
10
|
+
@klass = klass
|
11
|
+
@args = args
|
12
|
+
end
|
13
|
+
|
14
|
+
def encode
|
15
|
+
MultiJson.dump class: klass.to_s, args: args
|
16
|
+
end
|
17
|
+
|
18
|
+
def queue_name
|
19
|
+
StringExtensions.underscore(klass)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module LineUp
|
2
|
+
class StringExtensions
|
3
|
+
|
4
|
+
# See https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L90
|
5
|
+
def self.underscore(word)
|
6
|
+
word = word.to_s
|
7
|
+
word.gsub!(/::/, '/')
|
8
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
9
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
10
|
+
word.tr!("-", "_")
|
11
|
+
word.downcase!
|
12
|
+
word
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
data/lib/line_up.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'trouble'
|
2
|
+
|
3
|
+
require 'line_up/configuration'
|
4
|
+
require 'line_up/job'
|
5
|
+
|
6
|
+
module LineUp
|
7
|
+
RedisNotConfiguredError = Class.new(RuntimeError)
|
8
|
+
|
9
|
+
def self.push(application, jobclass, *args)
|
10
|
+
redis_for application do |redis|
|
11
|
+
job = Job.new jobclass, *args
|
12
|
+
redis.sadd 'queues', job.queue_name
|
13
|
+
redis.rpush "queue:#{job.queue_name}", job.encode
|
14
|
+
end
|
15
|
+
log caller, application, jobclass, *args
|
16
|
+
true
|
17
|
+
rescue Exception => exception
|
18
|
+
Trouble.notify exception, caller: caller[1], message: "LineUp could not enqueue a Job", code: :enqueue_failed, redis: config.redis.inspect, application: application.inspect, job: jobclass.inspect, args: args.inspect
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def self.redis_for(application, &block)
|
25
|
+
config.redis.namespace "#{StringExtensions.underscore(application)}:resque", &block
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.log(caller, application, jobclass, *args)
|
29
|
+
return unless config.logger
|
30
|
+
rows = ['LINEUP ENQUEUED A JOB']
|
31
|
+
rows << " | Location: #{caller.first}"
|
32
|
+
rows << " | Application: #{application.inspect}"
|
33
|
+
rows << " | Job Class: #{jobclass.inspect}"
|
34
|
+
rows << " \\ Arguments: #{args.inspect}\n"
|
35
|
+
config.logger.debug rows.join("\n")
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LineUp do
|
4
|
+
|
5
|
+
let(:application) { :otherApp }
|
6
|
+
let(:job) { :SendEmail }
|
7
|
+
let(:args) { [123, some: :thing] }
|
8
|
+
let(:redis) { $raw_redis }
|
9
|
+
let(:logger) { mock(:logger) }
|
10
|
+
|
11
|
+
let(:lineup) { LineUp }
|
12
|
+
|
13
|
+
describe '.push' do
|
14
|
+
it 'returns true if successful' do
|
15
|
+
lineup.push(application, job, *args).should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'registers the queue' do
|
19
|
+
lineup.push application, job, *args
|
20
|
+
queues = redis.smembers('other_app:resque:queues').should == %w{ send_email }
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'enqueues the job' do
|
24
|
+
lineup.push application, job, *args
|
25
|
+
jobs = redis.lrange('other_app:resque:queue:send_email', 0, -1)
|
26
|
+
jobs.size.should == 1
|
27
|
+
MultiJson.load(jobs.first).should == { 'class' => 'SendEmail', 'args' => [123, 'some' => 'thing'] }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a Logger' do
|
31
|
+
before do
|
32
|
+
lineup.config.logger = logger
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'logs the enqueueing and returns true' do
|
36
|
+
logger.should_receive(:debug) do |string|
|
37
|
+
string.should include('LINEUP ENQUEUED')
|
38
|
+
string.should include('line_up_spec.rb')
|
39
|
+
string.should include(':otherApp')
|
40
|
+
string.should include(':SendEmail')
|
41
|
+
string.should include('[123, {:some=>:thing}]')
|
42
|
+
end
|
43
|
+
lineup.push(application, job, *args).should be_true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when the key for the Queue Set is occupied by the wrong data format' do
|
48
|
+
before do
|
49
|
+
redis.set 'other_app:resque:queues', :anything_but_a_list
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'catches the error and returns false' do
|
53
|
+
Trouble.should_receive(:notify) do |exception, metadata|
|
54
|
+
exception.should be_instance_of Redis::CommandError
|
55
|
+
metadata[:code].should == :enqueue_failed
|
56
|
+
metadata[:application].should == ':otherApp'
|
57
|
+
metadata[:job].should == ':SendEmail'
|
58
|
+
metadata[:args].should == '[123, {:some=>:thing}]'
|
59
|
+
metadata[:caller].should include('line_up_spec.rb')
|
60
|
+
end
|
61
|
+
lineup.push(application, job, *args).should be_false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when the key for the List Job Queue is occupied by the wrong data format' do
|
66
|
+
before do
|
67
|
+
redis.set 'other_app:resque:queue:send_email', :anything_but_a_list
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'catches the error and returns false' do
|
71
|
+
Trouble.should_receive(:notify) do |exception, metadata|
|
72
|
+
exception.should be_instance_of Redis::CommandError
|
73
|
+
metadata[:code].should == :enqueue_failed
|
74
|
+
metadata[:application].should == ':otherApp'
|
75
|
+
metadata[:job].should == ':SendEmail'
|
76
|
+
metadata[:args].should == '[123, {:some=>:thing}]'
|
77
|
+
metadata[:caller].should include('line_up_spec.rb')
|
78
|
+
end
|
79
|
+
lineup.push(application, job, *args).should be_false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '.config' do
|
85
|
+
before do
|
86
|
+
LineUp.reset!
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'is an STDOUT logger' do
|
90
|
+
Logger.should_receive(:new).with(STDOUT).and_return logger
|
91
|
+
lineup.config.logger.should be logger
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'with Rails' do
|
95
|
+
before do
|
96
|
+
ensure_module :Rails
|
97
|
+
Rails.stub!(:logger).and_return(logger)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'is the Rails logger' do
|
101
|
+
lineup.config.logger.should be Rails.logger
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'redis-namespace'
|
2
|
+
require 'line_up'
|
3
|
+
|
4
|
+
def ensure_class_or_module(full_name, class_or_module)
|
5
|
+
full_name.to_s.split(/::/).inject(Object) do |context, name|
|
6
|
+
begin
|
7
|
+
context.const_get(name)
|
8
|
+
rescue NameError
|
9
|
+
if class_or_module == :class
|
10
|
+
context.const_set(name, Class.new)
|
11
|
+
else
|
12
|
+
context.const_set(name, Module.new)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def ensure_module(name)
|
19
|
+
ensure_class_or_module(name, :module)
|
20
|
+
end
|
21
|
+
|
22
|
+
def ensure_class(name)
|
23
|
+
ensure_class_or_module(name, :class)
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.configure do |config|
|
27
|
+
|
28
|
+
config.before do
|
29
|
+
$raw_redis = Redis.new(db: 14)
|
30
|
+
LineUp.config.redis = Redis::Namespace.new :myapp, redis: $raw_redis
|
31
|
+
LineUp.config.logger = nil
|
32
|
+
Trouble.stub!(:notify)
|
33
|
+
end
|
34
|
+
|
35
|
+
config.after do
|
36
|
+
$raw_redis.flushdb
|
37
|
+
LineUp.reset!
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: line_up
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- bukowskis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: trouble
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '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: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: multi_json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
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: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: redis-namespace
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
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'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: guard-rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rb-fsevent
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: No more need to maintain two separate redis connections when using namespaces.
|
111
|
+
LineUp does not even need Resque itself.
|
112
|
+
email:
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- lib/line_up/configuration.rb
|
118
|
+
- lib/line_up/job.rb
|
119
|
+
- lib/line_up/string_extensions.rb
|
120
|
+
- lib/line_up/version.rb
|
121
|
+
- lib/line_up.rb
|
122
|
+
- spec/lib/line_up_spec.rb
|
123
|
+
- spec/spec_helper.rb
|
124
|
+
- README.md
|
125
|
+
- LICENSE
|
126
|
+
homepage: https://github.com/bukowskis/line_up
|
127
|
+
licenses:
|
128
|
+
- MIT
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options:
|
131
|
+
- --encoding
|
132
|
+
- UTF-8
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 1.8.23
|
150
|
+
signing_key:
|
151
|
+
specification_version: 3
|
152
|
+
summary: Enqueue Resque Jobs directly via Redis so that you can choose the namespace
|
153
|
+
yourself
|
154
|
+
test_files: []
|