resque_solo 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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.ruby-version +1 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +34 -0
- data/README.md +45 -0
- data/Rakefile +12 -0
- data/lib/resque_ext/job.rb +40 -0
- data/lib/resque_ext/resque.rb +21 -0
- data/lib/resque_solo.rb +6 -0
- data/lib/resque_solo/queue.rb +82 -0
- data/lib/resque_solo/unique_job.rb +53 -0
- data/lib/resque_solo/version.rb +3 -0
- data/resque_solo.gemspec +27 -0
- data/test/fake_jobs.rb +38 -0
- data/test/job_test.rb +107 -0
- data/test/queue_test.rb +5 -0
- data/test/resque_test.rb +24 -0
- data/test/test_helper.rb +7 -0
- data/test/unique_job_test.rb +5 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1439a366dbc27ba7ab5fda8a4f2d3cd8249b2f2b
|
4
|
+
data.tar.gz: a4fbc3cfd7eb599ebdaab59c99be4bbdc7413c7b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: df1a343cf086b25b8b35d1f8d4498f481977d2c3bf123cd7238ae942706d74c466b37e0fd435cac47eae9c5c71f48f9e4d57f3b5548fe55b18dd22df9e36ed6a
|
7
|
+
data.tar.gz: 34d522a75a2e5dee71423271280b114e1a9d1c104643e4e4b5b36e1415ae47bf07b015f39f25406f5ca6922d10de293b99fc8e8e9992bfcaf8d6775dafaeb5eb
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
Copyright (c) 2010 Moviepilot GmbH http://moviepilot.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
14
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
15
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
17
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
19
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
|
21
|
+
|
22
|
+
Copyright (c) 2013 Tee Parham
|
23
|
+
|
24
|
+
MIT License
|
25
|
+
|
26
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
27
|
+
of this software and associated documentation files (the "Software"), to deal
|
28
|
+
in the Software without restriction, including without limitation the rights
|
29
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
30
|
+
copies of the Software, and to permit persons to whom the Software is
|
31
|
+
furnished to do so, subject to the following conditions:
|
32
|
+
|
33
|
+
The above copyright notice and this permission notice shall be included in
|
34
|
+
all copies or substantial portions of the Software.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# ResqueSolo
|
2
|
+
|
3
|
+
ResqueSolo is a resque plugin to add unique jobs to resque.
|
4
|
+
|
5
|
+
It is a re-write of [resque-loner](https://github.com/jayniz/resque-loner).
|
6
|
+
|
7
|
+
It requires ruby 2.0 and resque 1.25.
|
8
|
+
|
9
|
+
It removes the dependency on `Resque::Helpers`, which is deprecated for resque 2.0.
|
10
|
+
|
11
|
+
## Install
|
12
|
+
|
13
|
+
Add the gem to your Gemfile:
|
14
|
+
|
15
|
+
gem 'resque_solo'
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
class UpdateCat
|
21
|
+
include Resque::Plugins::UniqueJob
|
22
|
+
@queue = :cats
|
23
|
+
|
24
|
+
def self.perform(cat_id)
|
25
|
+
# do something
|
26
|
+
end
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
If you attempt to queue a unique job multiple times, it is ignored:
|
31
|
+
|
32
|
+
```
|
33
|
+
Resque.enqueue UpdateCat, 1
|
34
|
+
=> "OK"
|
35
|
+
Resque.enqueue UpdateCat, 1
|
36
|
+
=> "EXISTED"
|
37
|
+
Resque.enqueue UpdateCat, 1
|
38
|
+
=> "EXISTED"
|
39
|
+
Resque.size :cats
|
40
|
+
=> 1
|
41
|
+
Resque.enqueued? UpdateCat, 1
|
42
|
+
=> true
|
43
|
+
Resque.enqueued_in? :dogs, UpdateCat, 1
|
44
|
+
=> false
|
45
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Resque
|
2
|
+
class Job
|
3
|
+
class << self
|
4
|
+
# Mark an item as queued after Resque::Job.create has called Resque.push
|
5
|
+
def create_solo(queue, klass, *args)
|
6
|
+
return create_without_solo(queue, klass, *args) if Resque.inline?
|
7
|
+
item = {class: klass.to_s, args: args}
|
8
|
+
return "EXISTED" if ResqueSolo::Queue.queued?(queue, item)
|
9
|
+
# multi returns array of keys
|
10
|
+
create_return_value = false
|
11
|
+
Resque.redis.multi do
|
12
|
+
create_return_value = create_without_solo(queue, klass, *args)
|
13
|
+
ResqueSolo::Queue.mark_queued(queue, item)
|
14
|
+
end
|
15
|
+
create_return_value
|
16
|
+
end
|
17
|
+
|
18
|
+
# Mark an item as unqueued
|
19
|
+
def reserve_solo(queue)
|
20
|
+
item = reserve_without_solo(queue)
|
21
|
+
ResqueSolo::Queue.mark_unqueued(queue, item) if item && !Resque.inline?
|
22
|
+
item
|
23
|
+
end
|
24
|
+
|
25
|
+
# Mark all destroyed jobs as unqueued.
|
26
|
+
# The original method only returns the amount of jobs destroyed, but not the jobs themselves.
|
27
|
+
def destroy_solo(queue, klass, *args)
|
28
|
+
ResqueSolo::Queue.destroy(queue, klass, *args) unless Resque.inline?
|
29
|
+
destroy_without_solo(queue, klass, *args)
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :create_without_solo, :create
|
33
|
+
alias_method :create, :create_solo
|
34
|
+
alias_method :reserve_without_solo, :reserve
|
35
|
+
alias_method :reserve, :reserve_solo
|
36
|
+
alias_method :destroy_without_solo, :destroy
|
37
|
+
alias_method :destroy, :destroy_solo
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Resque
|
2
|
+
class << self
|
3
|
+
def enqueued?(klass, *args)
|
4
|
+
enqueued_in?(queue_from_class(klass), klass, *args )
|
5
|
+
end
|
6
|
+
|
7
|
+
def enqueued_in?(queue, klass, *args)
|
8
|
+
item = {class: klass.to_s, args: args}
|
9
|
+
return nil unless ResqueSolo::Queue.is_unique?(item)
|
10
|
+
ResqueSolo::Queue.queued?(queue, item)
|
11
|
+
end
|
12
|
+
|
13
|
+
def remove_queue_with_cleanup(queue)
|
14
|
+
remove_queue_without_cleanup(queue)
|
15
|
+
ResqueSolo::Queue.cleanup(queue)
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :remove_queue_without_cleanup, :remove_queue
|
19
|
+
alias_method :remove_queue, :remove_queue_with_cleanup
|
20
|
+
end
|
21
|
+
end
|
data/lib/resque_solo.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
module ResqueSolo
|
2
|
+
class Queue
|
3
|
+
class << self
|
4
|
+
def queued?(queue, item)
|
5
|
+
return false unless is_unique?(item)
|
6
|
+
redis.get(unique_key(queue, item)) == "1"
|
7
|
+
end
|
8
|
+
|
9
|
+
def mark_queued(queue, item)
|
10
|
+
return unless is_unique?(item)
|
11
|
+
key = unique_key(queue, item)
|
12
|
+
redis.set(key, 1)
|
13
|
+
ttl = item_ttl(item)
|
14
|
+
redis.expire(key, ttl) if ttl >= 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def mark_unqueued(queue, job)
|
18
|
+
item = job.is_a?(Resque::Job) ? job.payload : job
|
19
|
+
return unless is_unique?(item)
|
20
|
+
ttl = lock_after_execution_period(item)
|
21
|
+
if ttl == 0
|
22
|
+
redis.del(unique_key(queue, item))
|
23
|
+
else
|
24
|
+
redis.expire(unique_key(queue, item), ttl)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def unique_key(queue, item)
|
29
|
+
"solo:queue:#{queue}:job:#{const_for(item).redis_key(item)}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def is_unique?(item)
|
33
|
+
const_for(item).included_modules.include?(::Resque::Plugins::UniqueJob)
|
34
|
+
rescue NameError
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
def item_ttl(item)
|
39
|
+
const_for(item).ttl
|
40
|
+
rescue NameError
|
41
|
+
-1
|
42
|
+
end
|
43
|
+
|
44
|
+
def lock_after_execution_period(item)
|
45
|
+
const_for(item).lock_after_execution_period
|
46
|
+
rescue NameError
|
47
|
+
0
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy(queue, klass, *args)
|
51
|
+
klass = klass.to_s
|
52
|
+
redis_queue = "queue:#{queue}"
|
53
|
+
|
54
|
+
redis.lrange(redis_queue, 0, -1).each do |string|
|
55
|
+
json = JSON.parse(string)
|
56
|
+
next unless json['class'] == klass
|
57
|
+
next unless json['args'] == args if args.any?
|
58
|
+
ResqueSolo::Queue.mark_unqueued(queue, json)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def cleanup(queue)
|
63
|
+
keys = redis.keys("solo:queue:#{queue}:job:*")
|
64
|
+
redis.del(*keys) if keys.any?
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def redis
|
70
|
+
Resque.redis
|
71
|
+
end
|
72
|
+
|
73
|
+
def item_class(item)
|
74
|
+
item[:class] || item['class']
|
75
|
+
end
|
76
|
+
|
77
|
+
def const_for(item)
|
78
|
+
const_get item_class(item)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module Resque
|
4
|
+
module Plugins
|
5
|
+
module UniqueJob
|
6
|
+
def self.included(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Payload is what Resque stored for this job along with the job's class name:
|
12
|
+
# a hash containing :class and :args
|
13
|
+
def redis_key(payload)
|
14
|
+
payload = JSON.parse(JSON.generate(payload)) # todo - .stringify_keys
|
15
|
+
job = payload["class"]
|
16
|
+
args = payload["args"]
|
17
|
+
args.map! do |arg|
|
18
|
+
arg.is_a?(Hash) ? arg.sort : arg
|
19
|
+
end
|
20
|
+
|
21
|
+
Digest::MD5.hexdigest JSON.generate(class: job, args: args)
|
22
|
+
end
|
23
|
+
|
24
|
+
# The default ttl of a locking key is -1 (forever).
|
25
|
+
# To expire the lock after a certain amount of time, set a ttl (in seconds).
|
26
|
+
# For example:
|
27
|
+
#
|
28
|
+
# class FooJob
|
29
|
+
# include Resque::Plugins::UniqueJob
|
30
|
+
# @ttl = 40
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
def ttl
|
34
|
+
@ttl || -1
|
35
|
+
end
|
36
|
+
|
37
|
+
# The default ttl of a persisting key is 0, i.e. immediately deleted.
|
38
|
+
# Set lock_after_execution_period to block the execution
|
39
|
+
# of the job for a certain amount of time (in seconds).
|
40
|
+
# For example:
|
41
|
+
#
|
42
|
+
# class FooJob
|
43
|
+
# include Resque::Plugins::UniqueJob
|
44
|
+
# @lock_after_execution_period = 40
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
def lock_after_execution_period
|
48
|
+
@lock_after_execution_period || 0
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/resque_solo.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'resque_solo/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "resque_solo"
|
8
|
+
spec.version = ResqueSolo::VERSION
|
9
|
+
spec.authors = ["Tee Parham"]
|
10
|
+
spec.email = %w(tee@neighborland.com)
|
11
|
+
spec.description = %q{Resque plugin to add unique jobs}
|
12
|
+
spec.summary = %q{Resque plugin to add unique jobs}
|
13
|
+
spec.homepage = "https://github.com/teeparham/resque_solo"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = []
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|features)/})
|
19
|
+
spec.require_paths = %w(lib)
|
20
|
+
|
21
|
+
spec.required_ruby_version = ">= 2.0.0"
|
22
|
+
|
23
|
+
spec.add_dependency "resque", "~> 1.25.1"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
end
|
data/test/fake_jobs.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
class FakeJob
|
2
|
+
@queue = :normal
|
3
|
+
end
|
4
|
+
|
5
|
+
class FakeUniqueJob
|
6
|
+
include Resque::Plugins::UniqueJob
|
7
|
+
@queue = :unique
|
8
|
+
|
9
|
+
def self.perform(_)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class FailingUniqueJob
|
14
|
+
include Resque::Plugins::UniqueJob
|
15
|
+
@queue = :unique
|
16
|
+
|
17
|
+
def self.perform(_)
|
18
|
+
raise "Fail"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class UniqueJobWithTtl
|
23
|
+
include Resque::Plugins::UniqueJob
|
24
|
+
@queue = :unique_with_ttl
|
25
|
+
@ttl = 300
|
26
|
+
|
27
|
+
def self.perform(*_)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class UniqueJobWithLock
|
32
|
+
include Resque::Plugins::UniqueJob
|
33
|
+
@queue = :unique_with_lock
|
34
|
+
@lock_after_execution_period = 150
|
35
|
+
|
36
|
+
def self.perform(*_)
|
37
|
+
end
|
38
|
+
end
|
data/test/job_test.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class JobTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
Resque.redis.flushall
|
6
|
+
end
|
7
|
+
|
8
|
+
should "enqueue identical jobs once" do
|
9
|
+
Resque.enqueue FakeUniqueJob, "x"
|
10
|
+
Resque.enqueue FakeUniqueJob, "x"
|
11
|
+
assert_equal 1, Resque.size(:unique)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "allow the same jobs to be executed one after the other" do
|
15
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
16
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
17
|
+
assert_equal 1, Resque.size(:unique)
|
18
|
+
Resque.reserve(:unique)
|
19
|
+
assert_equal 0, Resque.size(:unique)
|
20
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
21
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
22
|
+
assert_equal 1, Resque.size(:unique)
|
23
|
+
end
|
24
|
+
|
25
|
+
should "consider equivalent hashes regardless of key order" do
|
26
|
+
Resque.enqueue FakeUniqueJob, bar: 1, foo: 2
|
27
|
+
Resque.enqueue FakeUniqueJob, foo: 2, bar: 1
|
28
|
+
assert_equal 1, Resque.size(:unique)
|
29
|
+
end
|
30
|
+
|
31
|
+
should "treat string and symbol keys equally" do
|
32
|
+
Resque.enqueue FakeUniqueJob, bar: 1, foo: 1
|
33
|
+
Resque.enqueue FakeUniqueJob, bar: 1, "foo" => 1
|
34
|
+
assert_equal 1, Resque.size(:unique)
|
35
|
+
end
|
36
|
+
|
37
|
+
should "mark jobs as unqueued, when Job.destroy is killing them" do
|
38
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
39
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
40
|
+
assert_equal 1, Resque.size(:unique)
|
41
|
+
Resque::Job.destroy(:unique, FakeUniqueJob)
|
42
|
+
assert_equal 0, Resque.size(:unique)
|
43
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
44
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
45
|
+
assert_equal 1, Resque.size(:unique)
|
46
|
+
end
|
47
|
+
|
48
|
+
should "mark jobs as unqueued when they raise an exception" do
|
49
|
+
2.times { Resque.enqueue( FailingUniqueJob, "foo" ) }
|
50
|
+
assert_equal 1, Resque.size(:unique)
|
51
|
+
worker = Resque::Worker.new(:unique)
|
52
|
+
worker.work 0
|
53
|
+
assert_equal 0, Resque.size(:unique)
|
54
|
+
2.times { Resque.enqueue( FailingUniqueJob, "foo" ) }
|
55
|
+
assert_equal 1, Resque.size(:unique)
|
56
|
+
end
|
57
|
+
|
58
|
+
should "report if a unique job is enqueued" do
|
59
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
60
|
+
assert Resque.enqueued?(FakeUniqueJob, "foo")
|
61
|
+
refute Resque.enqueued?(FakeUniqueJob, "bar")
|
62
|
+
end
|
63
|
+
|
64
|
+
should "report if a job is enqueued" do
|
65
|
+
default_queue = FakeUniqueJob.instance_variable_get(:@queue)
|
66
|
+
FakeUniqueJob.instance_variable_set(:@queue, :other)
|
67
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
68
|
+
assert Resque.enqueued_in?(:other, FakeUniqueJob, "foo")
|
69
|
+
FakeUniqueJob.instance_variable_set(:@queue, default_queue)
|
70
|
+
refute Resque.enqueued?(FakeUniqueJob, "foo")
|
71
|
+
end
|
72
|
+
|
73
|
+
should "cleanup when a queue is destroyed" do
|
74
|
+
Resque.enqueue FakeUniqueJob, "foo"
|
75
|
+
Resque.enqueue FailingUniqueJob, "foo"
|
76
|
+
Resque.remove_queue(:unique)
|
77
|
+
Resque.enqueue(FakeUniqueJob, "foo")
|
78
|
+
assert_equal 1, Resque.size(:unique)
|
79
|
+
end
|
80
|
+
|
81
|
+
should "honor ttl in the redis key" do
|
82
|
+
Resque.enqueue UniqueJobWithTtl
|
83
|
+
assert Resque.enqueued?(UniqueJobWithTtl)
|
84
|
+
keys = Resque.redis.keys "solo:queue:unique_with_ttl:job:*"
|
85
|
+
assert_equal 1, keys.length
|
86
|
+
assert_in_delta UniqueJobWithTtl.ttl, Resque.redis.ttl(keys.first), 2
|
87
|
+
end
|
88
|
+
|
89
|
+
should "not allow the same job to be enqueued after execution if lock_after_execution_period is set" do
|
90
|
+
Resque.enqueue UniqueJobWithLock, "foo"
|
91
|
+
Resque.enqueue UniqueJobWithLock, "foo"
|
92
|
+
assert_equal 1, Resque.size(:unique_with_lock)
|
93
|
+
Resque.reserve(:unique_with_lock)
|
94
|
+
assert_equal 0, Resque.size(:unique_with_lock)
|
95
|
+
Resque.enqueue UniqueJobWithLock, "foo"
|
96
|
+
assert_equal 0, Resque.size(:unique_with_lock)
|
97
|
+
end
|
98
|
+
|
99
|
+
should "honor lock_after_execution_period in the redis key" do
|
100
|
+
Resque.enqueue UniqueJobWithLock
|
101
|
+
Resque.reserve(:unique_with_lock)
|
102
|
+
keys = Resque.redis.keys "solo:queue:unique_with_lock:job:*"
|
103
|
+
assert_equal 1, keys.length
|
104
|
+
assert_in_delta UniqueJobWithLock.lock_after_execution_period, Resque.redis.ttl(keys.first), 2
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
data/test/queue_test.rb
ADDED
data/test/resque_test.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ResqueTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
Resque.redis.flushall
|
6
|
+
end
|
7
|
+
|
8
|
+
should "enqueue normal jobs" do
|
9
|
+
Resque.enqueue FakeJob, "x"
|
10
|
+
Resque.enqueue FakeJob, "x"
|
11
|
+
assert_equal 2, Resque.size(:normal)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "not be able to report if a non-unique job was enqueued" do
|
15
|
+
assert_nil Resque.enqueued?(FakeJob)
|
16
|
+
end
|
17
|
+
|
18
|
+
should "not raise when deleting an empty queue" do
|
19
|
+
assert_nothing_raised do
|
20
|
+
Resque.remove_queue(:unique)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resque_solo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tee Parham
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: resque
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.25.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.25.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Resque plugin to add unique jobs
|
56
|
+
email:
|
57
|
+
- tee@neighborland.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- .ruby-version
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- lib/resque_ext/job.rb
|
69
|
+
- lib/resque_ext/resque.rb
|
70
|
+
- lib/resque_solo.rb
|
71
|
+
- lib/resque_solo/queue.rb
|
72
|
+
- lib/resque_solo/unique_job.rb
|
73
|
+
- lib/resque_solo/version.rb
|
74
|
+
- resque_solo.gemspec
|
75
|
+
- test/fake_jobs.rb
|
76
|
+
- test/job_test.rb
|
77
|
+
- test/queue_test.rb
|
78
|
+
- test/resque_test.rb
|
79
|
+
- test/test_helper.rb
|
80
|
+
- test/unique_job_test.rb
|
81
|
+
homepage: https://github.com/teeparham/resque_solo
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 2.0.0
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.1.11
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Resque plugin to add unique jobs
|
105
|
+
test_files:
|
106
|
+
- test/fake_jobs.rb
|
107
|
+
- test/job_test.rb
|
108
|
+
- test/queue_test.rb
|
109
|
+
- test/resque_test.rb
|
110
|
+
- test/test_helper.rb
|
111
|
+
- test/unique_job_test.rb
|