afterparty 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +10 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +57 -0
- data/Rakefile +6 -0
- data/afterparty.gemspec +25 -0
- data/dump.rdb +0 -0
- data/lib/afterparty/queue_helpers.rb +67 -0
- data/lib/afterparty/redis_queue.rb +57 -0
- data/lib/afterparty/threaded_queue_consumer.rb +58 -0
- data/lib/afterparty/version.rb +3 -0
- data/lib/afterparty.rb +14 -0
- data/spec/helpers.rb +28 -0
- data/spec/redis_queue_spec.rb +97 -0
- data/spec/spec_helper.rb +11 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: d5a18d9460144527504869b72c7a377ce2c6eda0
|
4
|
+
data.tar.gz: 4d9b52a88c5fea21d37da73b1a13f5f5bf180c9e
|
5
|
+
!binary "U0hBNTEy":
|
6
|
+
metadata.gz: d6323eb6eb7a72b1090207d498ae02890dbfca347bdc37414453f67441725e966b4205651d53d4756e15ce7a786ff1a1058c98572439c67e931ab0f150ce70c7
|
7
|
+
data.tar.gz: 1888cd7d556ee3f5164935ac9fb7a9b57dcf9fb1808ff8eae57315bd8175f3080e2a1dca599437bbf87770f11acc48b598fd62a1272a4c8077f0c7385304d9a1
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec' do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
watch('config/routes.rb') { "spec/routing" }
|
15
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
+
|
17
|
+
# Capybara features specs
|
18
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
19
|
+
|
20
|
+
# Turnip features and steps
|
21
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
23
|
+
end
|
24
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Hank Stoever
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# Afterparty
|
2
|
+
|
3
|
+
A Rails 4 compatible queue with support for executing jobs in the future and serialization with Redis.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Make sure you've installed [redis](http://redis.io) on your machine.
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
~~~Ruby
|
12
|
+
gem 'afterparty'
|
13
|
+
~~~
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install afterparty
|
22
|
+
|
23
|
+
In your desired application environment, like `application.rb`:
|
24
|
+
|
25
|
+
~~~Ruby
|
26
|
+
config.queue = Afterparty::RedisQueue.new
|
27
|
+
~~~
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
A `job` is a ruby object with a `run` method.
|
32
|
+
|
33
|
+
~~~Ruby
|
34
|
+
class Job
|
35
|
+
def run
|
36
|
+
puts "Hello!"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
~~~
|
40
|
+
|
41
|
+
Then add it to the queue at any time.
|
42
|
+
|
43
|
+
~~~Ruby
|
44
|
+
Rails.queue << Job.new
|
45
|
+
~~~
|
46
|
+
|
47
|
+
If your job responds to an `execute_at` method, the queue will wait to process that job until the specified time.
|
48
|
+
|
49
|
+
## Contributing
|
50
|
+
|
51
|
+
1. Fork it
|
52
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
53
|
+
3. Add a test in `spec/redis_queue_spec.rb`
|
54
|
+
4. Make sure tests pass when you run `rake`
|
55
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
56
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
57
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/afterparty.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'afterparty/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "afterparty"
|
8
|
+
spec.version = Afterparty::VERSION
|
9
|
+
spec.authors = ["Hank Stoever"]
|
10
|
+
spec.email = ["hstove@gmail.com"]
|
11
|
+
spec.description = %q{Rails 4 compatible queue with support for executing jobs later.}
|
12
|
+
spec.summary = %q{Rails 4 compatible queue with support for executing jobs later.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "redis"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
end
|
data/dump.rdb
ADDED
Binary file
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Afterparty
|
2
|
+
module QueueHelpers
|
3
|
+
def [] namespace
|
4
|
+
@temp_namespace = namespace
|
5
|
+
end
|
6
|
+
|
7
|
+
def redis_queue_name
|
8
|
+
"afterparty_#{@temp_namespace || @options[:namespace]}_queue"
|
9
|
+
end
|
10
|
+
|
11
|
+
def clear
|
12
|
+
redis_call :del
|
13
|
+
end
|
14
|
+
|
15
|
+
def redis_call command, *args
|
16
|
+
result = Afterparty.redis.send(command, redis_queue_name, *args)
|
17
|
+
@temp_namespace = nil
|
18
|
+
result
|
19
|
+
end
|
20
|
+
|
21
|
+
def async_redis_call &block
|
22
|
+
Afterparty.redis.pipelined &block
|
23
|
+
end
|
24
|
+
|
25
|
+
def jobs
|
26
|
+
_jobs = redis_call(:zrange, 0, -1)
|
27
|
+
_jobs.each_with_index do |job, i|
|
28
|
+
_jobs[i] = Marshal.load(job)
|
29
|
+
end
|
30
|
+
_jobs
|
31
|
+
end
|
32
|
+
|
33
|
+
def jobs_with_scores
|
34
|
+
redis_call :zrange, 0, -1, {withscores: true}
|
35
|
+
end
|
36
|
+
|
37
|
+
def valid_jobs
|
38
|
+
redis_call :zrangebyscore, 0, Time.now.to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def jobs_empty?
|
42
|
+
count = total_jobs_count
|
43
|
+
# ap count
|
44
|
+
count == 0
|
45
|
+
end
|
46
|
+
|
47
|
+
def total_jobs_count
|
48
|
+
redis_call(:zcount, "-inf", "+inf")
|
49
|
+
end
|
50
|
+
|
51
|
+
def redis
|
52
|
+
@@redis
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
# returns true if job has an :execute_at value
|
58
|
+
def job_valid? job
|
59
|
+
job.respond_to?(:execute_at) && !job.execute_at.nil?
|
60
|
+
end
|
61
|
+
|
62
|
+
# return timestamp of :execute_at or current time
|
63
|
+
def queue_time job
|
64
|
+
time = job_valid?(job) ? job.execute_at.to_i : Time.now.to_i
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Afterparty
|
2
|
+
class RedisQueue
|
3
|
+
attr_accessor :redis, :options, :temp_namespace, :consumer
|
4
|
+
include Afterparty::QueueHelpers
|
5
|
+
|
6
|
+
def initialize options={}, consumer_options={}
|
7
|
+
@consumer = ThreadedQueueConsumer.new(self, consumer_options).start
|
8
|
+
@options = options
|
9
|
+
@options[:namespace] ||= "default"
|
10
|
+
@options[:sleep] ||= 5
|
11
|
+
@mutex = Mutex.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def push job
|
15
|
+
@mutex.synchronize do
|
16
|
+
return nil if job.nil?
|
17
|
+
async_redis_call{ redis_call :zadd, queue_time(job), Marshal.dump(job) }
|
18
|
+
@consumer.start unless @consumer.thread.alive?
|
19
|
+
@temp_namespace = nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias :<< :push
|
23
|
+
alias :eng :push
|
24
|
+
|
25
|
+
def pop
|
26
|
+
@mutex.synchronize do
|
27
|
+
while true do
|
28
|
+
if jobs_empty?
|
29
|
+
@consumer.shutdown
|
30
|
+
elsif !(_jobs = valid_jobs).empty?
|
31
|
+
job_dump = _jobs[0]
|
32
|
+
async_redis_call do
|
33
|
+
redis_call :zrem, job_dump
|
34
|
+
@temp_namespace = "completed"
|
35
|
+
redis_call :zadd, Time.now.to_i, job_dump
|
36
|
+
end
|
37
|
+
return Marshal.load(job_dump)
|
38
|
+
end
|
39
|
+
sleep(@options[:sleep])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class TestRedisQueue < RedisQueue
|
46
|
+
attr_accessor :completed_jobs
|
47
|
+
|
48
|
+
def initialize opts={}, consumer_opts={}
|
49
|
+
super
|
50
|
+
@completed_jobs = []
|
51
|
+
@exceptions = []
|
52
|
+
end
|
53
|
+
def handle_exception job, exception
|
54
|
+
@exceptions << [job, exception]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Afterparty
|
2
|
+
|
3
|
+
# inspired by the rails 4 implementation:
|
4
|
+
# https://github.com/rails/rails/blob/jobs/activesupport/lib/active_support/queueing.rb
|
5
|
+
|
6
|
+
# The threaded consumer will run jobs in a background thread in
|
7
|
+
# development mode or in a VM where running jobs on a thread in
|
8
|
+
# production mode makes sense.
|
9
|
+
#
|
10
|
+
# When the process exits, the consumer pushes a nil onto the
|
11
|
+
# queue and joins the thread, which will ensure that all jobs
|
12
|
+
# are executed before the process finally dies.
|
13
|
+
class ThreadedQueueConsumer
|
14
|
+
attr_accessor :logger, :thread
|
15
|
+
|
16
|
+
def initialize(queue, options = {})
|
17
|
+
@queue = queue
|
18
|
+
@logger = options[:logger]
|
19
|
+
@fallback_logger = Logger.new($stderr)
|
20
|
+
end
|
21
|
+
|
22
|
+
def start
|
23
|
+
@thread = Thread.new { consume }
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def shutdown
|
28
|
+
@queue.push nil
|
29
|
+
@thread.join
|
30
|
+
end
|
31
|
+
|
32
|
+
def drain
|
33
|
+
while job = @queue.pop(true)
|
34
|
+
job.run
|
35
|
+
end
|
36
|
+
rescue ThreadError
|
37
|
+
end
|
38
|
+
|
39
|
+
def consume
|
40
|
+
while job = @queue.pop
|
41
|
+
if @queue.respond_to? :completed_jobs
|
42
|
+
@queue.completed_jobs << job
|
43
|
+
end
|
44
|
+
run job
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def run(job)
|
49
|
+
job.run
|
50
|
+
rescue Exception => exception
|
51
|
+
handle_exception job, exception
|
52
|
+
end
|
53
|
+
|
54
|
+
def handle_exception(job, exception)
|
55
|
+
(logger || @fallback_logger).error "Job Error: #{job.inspect}\n#{exception.message}\n#{exception.backtrace.join("\n")}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/afterparty.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'afterparty/queue_helpers'
|
3
|
+
require 'afterparty/redis_queue'
|
4
|
+
Dir[File.expand_path('../afterparty/*', __FILE__)].each { |f| require f }
|
5
|
+
|
6
|
+
|
7
|
+
module Afterparty
|
8
|
+
def self.redis
|
9
|
+
@@redis
|
10
|
+
end
|
11
|
+
def self.redis=(redis)
|
12
|
+
@@redis = redis
|
13
|
+
end
|
14
|
+
end
|
data/spec/helpers.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Afterparty
|
2
|
+
module QueueTestHelpers
|
3
|
+
|
4
|
+
def test_job later=false, &block
|
5
|
+
job = block ? TestJob.new(block) : TestJob.new
|
6
|
+
job.execute_at = Time.now + (later) if later
|
7
|
+
@block = block
|
8
|
+
job
|
9
|
+
end
|
10
|
+
|
11
|
+
def chill seconds
|
12
|
+
t = Time.now
|
13
|
+
while Time.now < (t + seconds); end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class TestJob
|
19
|
+
attr_accessor :execute_at
|
20
|
+
|
21
|
+
def initialize &block
|
22
|
+
@block = block
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
@block.call if @block
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe Afterparty::RedisQueue do
|
3
|
+
before do
|
4
|
+
require 'open-uri'
|
5
|
+
uri = URI.parse("redis://localhost:6379")
|
6
|
+
redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
|
7
|
+
Afterparty.redis = redis
|
8
|
+
@q = Afterparty::TestRedisQueue.new({sleep: 0.5})
|
9
|
+
end
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
@q.completed_jobs.clear
|
13
|
+
@q.clear
|
14
|
+
Afterparty.redis.quit
|
15
|
+
end
|
16
|
+
|
17
|
+
it "pushes nil without errors" do
|
18
|
+
@q.push(nil)
|
19
|
+
@q.jobs.should eq([])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "adds items to the queue" do
|
23
|
+
@q.push(test_job)
|
24
|
+
@q.total_jobs_count.should eq(1)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "executes the job" do
|
28
|
+
job = TestJob.new
|
29
|
+
@q.push(job)
|
30
|
+
complete.size.should eq(0)
|
31
|
+
chill(3)
|
32
|
+
complete.size.should eq(1)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "removes items from the queue after running them" do
|
36
|
+
@q.push TestJob.new
|
37
|
+
chill(1)
|
38
|
+
@q.jobs.should_not include(@job)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "doesn't execute jobs that execute in a while" do
|
42
|
+
job = TestJob.new
|
43
|
+
job.execute_at = Time.now + 200
|
44
|
+
@q.push job
|
45
|
+
chill(3)
|
46
|
+
complete.size.should eq(0)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "waits the correct amount of time to execute a job" do
|
50
|
+
job = TestJob.new
|
51
|
+
job.execute_at = Time.now + 2
|
52
|
+
@q.push(job)
|
53
|
+
chill(8)
|
54
|
+
complete.size.should eq(1)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "doesn't execute the job synchronously when added" do
|
58
|
+
job = test_job 100
|
59
|
+
t = Time.now
|
60
|
+
@q.push(job)
|
61
|
+
(Time.now - t).should <= 1
|
62
|
+
end
|
63
|
+
|
64
|
+
it "executes jobs in the right order" do
|
65
|
+
late_job = test_job 60*10
|
66
|
+
early_job = test_job
|
67
|
+
@q.push(late_job)
|
68
|
+
@q.push(early_job)
|
69
|
+
chill(3)
|
70
|
+
complete.size.should eq(1)
|
71
|
+
complete[0].execute_at.should be(nil)
|
72
|
+
end
|
73
|
+
|
74
|
+
class ErrorJob
|
75
|
+
attr_accessor :execute_at
|
76
|
+
|
77
|
+
def run
|
78
|
+
raise "hello"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def complete
|
83
|
+
@q.completed_jobs
|
84
|
+
end
|
85
|
+
|
86
|
+
def error_job later=nil
|
87
|
+
job = ErrorJob.new
|
88
|
+
job.execute_at = Time.now + later if later
|
89
|
+
job
|
90
|
+
end
|
91
|
+
|
92
|
+
def chill seconds
|
93
|
+
t = Time.now
|
94
|
+
while Time.now < (t + seconds); end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'awesome_print'
|
4
|
+
require 'redis'
|
5
|
+
require 'afterparty' # and any other gems you need
|
6
|
+
require 'helpers'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
# some (optional) config here
|
10
|
+
config.include Afterparty::QueueTestHelpers
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: afterparty
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hank Stoever
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redis
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
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: Rails 4 compatible queue with support for executing jobs later.
|
56
|
+
email:
|
57
|
+
- hstove@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- .rspec
|
64
|
+
- .travis.yml
|
65
|
+
- Gemfile
|
66
|
+
- Guardfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- afterparty.gemspec
|
71
|
+
- dump.rdb
|
72
|
+
- lib/afterparty.rb
|
73
|
+
- lib/afterparty/queue_helpers.rb
|
74
|
+
- lib/afterparty/redis_queue.rb
|
75
|
+
- lib/afterparty/threaded_queue_consumer.rb
|
76
|
+
- lib/afterparty/version.rb
|
77
|
+
- spec/helpers.rb
|
78
|
+
- spec/redis_queue_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
homepage: ''
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.0.3
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Rails 4 compatible queue with support for executing jobs later.
|
104
|
+
test_files:
|
105
|
+
- spec/helpers.rb
|
106
|
+
- spec/redis_queue_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
has_rdoc:
|