resque-kalashnikov 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +99 -0
- data/Rakefile +7 -0
- data/demo/.gitignore +15 -0
- data/demo/Gemfile +31 -0
- data/demo/README.rdoc +9 -0
- data/demo/Rakefile +7 -0
- data/demo/app/assets/images/rails.png +0 -0
- data/demo/app/assets/javascripts/application.js +13 -0
- data/demo/app/assets/stylesheets/application.css +13 -0
- data/demo/app/controllers/application_controller.rb +3 -0
- data/demo/app/controllers/test_controller.rb +15 -0
- data/demo/app/helpers/application_helper.rb +2 -0
- data/demo/app/mailers/.gitkeep +0 -0
- data/demo/app/models/.gitkeep +0 -0
- data/demo/app/workers/slow_http_request.rb +3 -0
- data/demo/config.ru +4 -0
- data/demo/config/application.rb +65 -0
- data/demo/config/boot.rb +6 -0
- data/demo/config/environment.rb +5 -0
- data/demo/config/environments/development.rb +26 -0
- data/demo/config/environments/production.rb +51 -0
- data/demo/config/environments/test.rb +35 -0
- data/demo/config/initializers/backtrace_silencers.rb +7 -0
- data/demo/config/initializers/inflections.rb +15 -0
- data/demo/config/initializers/mime_types.rb +5 -0
- data/demo/config/initializers/secret_token.rb +7 -0
- data/demo/config/initializers/session_store.rb +8 -0
- data/demo/config/initializers/wrap_parameters.rb +10 -0
- data/demo/config/locales/en.yml +5 -0
- data/demo/config/routes.rb +11 -0
- data/demo/db/seeds.rb +7 -0
- data/demo/lib/assets/.gitkeep +0 -0
- data/demo/lib/tasks/.gitkeep +0 -0
- data/demo/log/.gitkeep +0 -0
- data/demo/public/404.html +26 -0
- data/demo/public/422.html +26 -0
- data/demo/public/500.html +25 -0
- data/demo/public/favicon.ico +0 -0
- data/demo/public/index.html +12 -0
- data/demo/public/robots.txt +5 -0
- data/demo/script/rails +6 -0
- data/demo/script/resque_async.rb +29 -0
- data/demo/vendor/assets/javascripts/.gitkeep +0 -0
- data/demo/vendor/assets/stylesheets/.gitkeep +0 -0
- data/demo/vendor/plugins/.gitkeep +0 -0
- data/demo/zeus.json +22 -0
- data/lib/event_machine/forced_stop.rb +3 -0
- data/lib/resque/catridge.rb +87 -0
- data/lib/resque/plugins/resque_kalashnikov/resque_kalashnikov.rb +130 -0
- data/lib/resque_kalashnikov.rb +17 -0
- data/lib/resque_kalashnikov/delegation.rb +153 -0
- data/lib/resque_kalashnikov/http_request.rb +64 -0
- data/lib/resque_kalashnikov/railtie.rb +10 -0
- data/lib/resque_kalashnikov/server.rb +50 -0
- data/lib/resque_kalashnikov/server/views/catridges.erb +57 -0
- data/lib/resque_kalashnikov/version.rb +3 -0
- data/lib/tasks.rb +34 -0
- data/resque-kalashnikov.gemspec +30 -0
- data/screenshot.png +0 -0
- data/spec/catridge_spec.rb +42 -0
- data/spec/http_request_spec.rb +84 -0
- data/spec/server_spec.rb +46 -0
- data/spec/spec_helper.rb +56 -0
- data/spec/support/stub_server.rb +46 -0
- data/spec/worker_spec.rb +113 -0
- data/tasks/resque_kalashnikov.rake +2 -0
- metadata +267 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ResqueKalashnikov::HttpRequest' do
|
4
|
+
|
5
|
+
def build(attrs={})
|
6
|
+
url = attrs.delete('url') || async_server_url
|
7
|
+
http_method = attrs.delete('http_method') || 'get'
|
8
|
+
ResqueKalashnikov::HttpRequest.new(url, http_method, attrs)
|
9
|
+
end
|
10
|
+
|
11
|
+
def success_response
|
12
|
+
{ :status => 200, :body => "success", :headers => {} }
|
13
|
+
end
|
14
|
+
|
15
|
+
['get', 'post', 'delete', 'put'].each do |http_method|
|
16
|
+
it "stores valid #{http_method} methods" do
|
17
|
+
stub_request(http_method.to_sym, async_server_url).to_return success_response
|
18
|
+
EM.synchrony do
|
19
|
+
build("http_method" => http_method).send(:http_request).response.should == 'success'
|
20
|
+
EM.stop
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
['head', 'options', 'patch'].each do |http_method|
|
26
|
+
it "stores valid #{http_method} methods" do
|
27
|
+
stub_request(http_method.to_sym, async_server_url).to_return success_response
|
28
|
+
EM.synchrony do
|
29
|
+
build("http_method" => http_method).send(:http_request).response.should == ''
|
30
|
+
EM.stop
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'stores invalid methods as GET' do
|
36
|
+
stub_request(:get, async_server_url).to_return success_response
|
37
|
+
EM.synchrony do
|
38
|
+
build.send(:http_request).response.should == 'success'
|
39
|
+
build('http_method' => 'foobar').send(:http_request).response.should == 'success'
|
40
|
+
EM.stop
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'handles misc options' do
|
45
|
+
stub_request(:get, async_server_url)
|
46
|
+
.with(:query => {"a" => ["b", "c"], "d" => "e"})
|
47
|
+
.to_return(success_response)
|
48
|
+
|
49
|
+
stub_request(:post, "http://127.0.0.1:8081/?d=e&n=1&kind=async")
|
50
|
+
.to_return(success_response)
|
51
|
+
|
52
|
+
EM.synchrony do
|
53
|
+
build(
|
54
|
+
"a" => ["b", "c"],
|
55
|
+
"d" => "e"
|
56
|
+
).send(:http_request).response.should == 'success'
|
57
|
+
|
58
|
+
build(
|
59
|
+
"url" => async_server_url({n: 1, kind: 'async'}),
|
60
|
+
"http_method" => "post",
|
61
|
+
"d" => "e"
|
62
|
+
).send(:http_request).response.should == 'success'
|
63
|
+
EM.stop
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'error handling' do
|
68
|
+
it 'handles 4xx responses' do
|
69
|
+
stub_request(:any, async_server_url).to_return(:status => [404, "Not Found"])
|
70
|
+
EM.synchrony do
|
71
|
+
build.send(:http_request).response_header.status.should == 404
|
72
|
+
EM.stop
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'handles 5xx responses' do
|
77
|
+
stub_request(:any, async_server_url).to_return(:status => [500, "Internal Server Error"])
|
78
|
+
EM.synchrony do
|
79
|
+
build.send(:http_request).response_header.status.should == 500
|
80
|
+
EM.stop
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "resque_kalashnikov/server"
|
3
|
+
|
4
|
+
ENV['RACK_ENV'] = 'test'
|
5
|
+
|
6
|
+
describe ResqueKalashnikov::Server do
|
7
|
+
require 'rack/test'
|
8
|
+
include Rack::Test::Methods
|
9
|
+
|
10
|
+
def app
|
11
|
+
Resque::Server
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has Kalashnikov tab' do
|
15
|
+
get '/overview'
|
16
|
+
last_response.body.should =~ /kalashnikov/
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'can show Kalashnikov tab' do
|
20
|
+
get '/kalashnikov'
|
21
|
+
last_response.status.should == 200
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'actions' do
|
25
|
+
before do
|
26
|
+
@request_key = Base64.encode64 Resque.encode [SlowHttpRequest, [async_server_url, {method: 'post'}]]
|
27
|
+
@fake_redis = double
|
28
|
+
Redis.stub(:connect).and_return(@fake_redis)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'can retry jobs' do
|
32
|
+
@fake_redis.should_receive(:rpush).once
|
33
|
+
post '/kalashnikov/retry/500', {request_key: @request_key}
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'can reset misfire count' do
|
37
|
+
@fake_redis.should_receive(:rpush).once
|
38
|
+
post '/kalashnikov/retry/500', {request_key: @request_key}
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'can reset everyhing' do
|
42
|
+
Resque::Catridge.should_receive(:reset_stats)
|
43
|
+
get '/kalashnikov/reset_stats'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'resque'
|
3
|
+
require 'em-synchrony'
|
4
|
+
require 'em-synchrony/em-hiredis'
|
5
|
+
require 'webmock/rspec'
|
6
|
+
|
7
|
+
$dir = File.dirname(File.expand_path(__FILE__))
|
8
|
+
$LOAD_PATH.unshift $dir + '/../lib'
|
9
|
+
require 'resque_kalashnikov'
|
10
|
+
require 'support/stub_server'
|
11
|
+
$TESTING = true
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.filter_run :focus
|
17
|
+
config.order = 'random'
|
18
|
+
|
19
|
+
config.before do
|
20
|
+
Redis.connect.flushall
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class SlowHttpRequest < ResqueKalashnikov::HttpRequest
|
25
|
+
@queue = :async_queue
|
26
|
+
|
27
|
+
def handle http
|
28
|
+
super
|
29
|
+
File.open("/tmp/kalashnikov-#{$$}.log", "a") do |f|
|
30
|
+
f.write "#{DateTime.now}:#{http.response_header.status}:#{http.response}\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def async_server(response_status=200, delay=0)
|
36
|
+
WebMock.allow_net_connect!
|
37
|
+
EM.synchrony do
|
38
|
+
#EM::HttpRequest.new('http://httplogger.herokuapp.com/bvlog/clear').get if async_server_url['herokuapp']
|
39
|
+
Resque.redis = EM::Synchrony::ConnectionPool.new(size: 3) do
|
40
|
+
EM::Hiredis.connect
|
41
|
+
end
|
42
|
+
#Resque.redis.flushall # reset state in Resque object
|
43
|
+
s = StubServer.new response_status, delay
|
44
|
+
yield
|
45
|
+
s.stop
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def async_server_url(attrs={})
|
50
|
+
#return "http://httplogger.herokuapp.com/bvlog/get"
|
51
|
+
if attrs.empty?
|
52
|
+
"http://127.0.0.1:8081"
|
53
|
+
else
|
54
|
+
"http://127.0.0.1:8081/?n=#{attrs[:n]}&kind=#{attrs[:kind]}"
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
# thanks @igrigorik
|
4
|
+
# https://github.com/igrigorik/em-synchrony/blob/master/spec/helper/stub-http-server.rb
|
5
|
+
class StubServer
|
6
|
+
module Server
|
7
|
+
attr_accessor :responses, :delay
|
8
|
+
def receive_data(data)
|
9
|
+
EM.add_timer(@delay) {
|
10
|
+
send_data @responses.sample
|
11
|
+
close_connection_after_writing
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(response_code=[200], delay=0, port=8081)
|
17
|
+
@sig = EventMachine::start_server("127.0.0.1", port, Server) { |s|
|
18
|
+
response_map = {
|
19
|
+
"500" => "HTTP/1.0 500 Internal Server Error\r\nConnection: close\r\n\r\nFail: 500",
|
20
|
+
"404" => "HTTP/1.0 404 Not Found\r\nConnection: close\r\n\r\nNot Found: 404",
|
21
|
+
"200" => "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nSuccess",
|
22
|
+
}
|
23
|
+
s.responses = response_map.select { |k,v| response_code.to_s.include? k } .values
|
24
|
+
s.delay = delay
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def stop
|
29
|
+
EventMachine.stop_server @sig
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
if __FILE__ == $0
|
34
|
+
EM.run do
|
35
|
+
s = StubServer.new(ARGV || [200], 0)
|
36
|
+
puts 'Started on http://localhost:8081/'
|
37
|
+
|
38
|
+
['TERM', 'INT', 'QUIT'].each do |signal|
|
39
|
+
trap(signal) do
|
40
|
+
puts 'Finished'
|
41
|
+
s.stop
|
42
|
+
EM.stop
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/worker_spec.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
DELAY = 0.5
|
4
|
+
|
5
|
+
describe 'Resque::Worker' do
|
6
|
+
before do
|
7
|
+
Resque.before_first_fork = nil
|
8
|
+
Resque.before_fork = nil
|
9
|
+
Resque.after_fork = nil
|
10
|
+
@worker = Resque::Worker.new(:async_queue, :sync_queue)
|
11
|
+
#@worker.verbose = true # useful to see sync/async difference
|
12
|
+
end
|
13
|
+
|
14
|
+
def now(); Time.now.to_f; end
|
15
|
+
|
16
|
+
def create_async_job(attrs={})
|
17
|
+
attrs.merge! kind: 'async'
|
18
|
+
Resque::Job.create(:async_queue, SlowHttpRequest, async_server_url(attrs), attrs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_sync_job(attrs={})
|
22
|
+
attrs.merge! kind: 'sync'
|
23
|
+
Resque::Job.create(:sync_queue, SlowHttpRequest, async_server_url(attrs), attrs)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'has proper name' do
|
27
|
+
@worker.inspect.should =~ /KalashnikovWorker/
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'makes acquires jobs with Hiredis#blpop' do
|
31
|
+
create_sync_job
|
32
|
+
@worker.reserve.should be_kind_of Resque::Job
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'differs async jobs' do
|
36
|
+
create_async_job
|
37
|
+
@worker.can_do_job_async?(Resque::Job.reserve :async_queue).should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'differs sync jobs' do
|
41
|
+
create_sync_job
|
42
|
+
@worker.can_do_job_async?(Resque::Job.reserve :sync_queue).should be_false
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'handles async queues with fibers' do
|
46
|
+
queue_size = 20
|
47
|
+
queue_size.times { |n| create_async_job(n: n) }
|
48
|
+
|
49
|
+
async_server([200], DELAY) do
|
50
|
+
start = now
|
51
|
+
@worker.work(0) do |job|
|
52
|
+
# block yields in Worker#perform in "ensure" part
|
53
|
+
#
|
54
|
+
# this is too early - Fiber hasn't finished till this moment
|
55
|
+
# if theirs count is small, it's still ok
|
56
|
+
#
|
57
|
+
# if there were 100 jobs - they'll have managed ~60
|
58
|
+
# but uncommenting "if" statement leads to ever-hook in EM
|
59
|
+
# having ~30 alive fibers after having done 100 jobs
|
60
|
+
#
|
61
|
+
# TLDR: kalashnikov-worker is hard to stop with block - use signals
|
62
|
+
@worker.shutdown #if Resque.size(:async_queue) == 0
|
63
|
+
end
|
64
|
+
|
65
|
+
# O(1)
|
66
|
+
(now - start).should be_within(DELAY*2).of(DELAY)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'handles sync queues with processes' do
|
71
|
+
queue_size = 3
|
72
|
+
queue_size.times { |n| create_sync_job(n: n) }
|
73
|
+
|
74
|
+
async_server([200], DELAY) do
|
75
|
+
start = now
|
76
|
+
@worker.work(0) do |job|
|
77
|
+
@worker.shutdown if Resque.size(:sync_queue) == 0
|
78
|
+
end
|
79
|
+
|
80
|
+
# O(n)
|
81
|
+
(now - start).should be_within(DELAY*queue_size*2).of(DELAY*queue_size)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'handles 404 & 500 error async' do
|
86
|
+
queue_size = 20
|
87
|
+
queue_size.times { |n| create_async_job(n: n) }
|
88
|
+
async_server([500, 404], DELAY) do
|
89
|
+
start = now
|
90
|
+
@worker.work(0) do |job|
|
91
|
+
@worker.shutdown #if Resque.size(:async_queue) == 0
|
92
|
+
end
|
93
|
+
|
94
|
+
# O(1)
|
95
|
+
(now - start).should be_within(DELAY*2).of(DELAY)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'handles random async jobs' do
|
100
|
+
queue_size = 20
|
101
|
+
queue_size.times { |n| create_async_job(n: n) }
|
102
|
+
|
103
|
+
async_server([200, 404, 500], DELAY) do
|
104
|
+
start = now
|
105
|
+
@worker.work(0) do |job|
|
106
|
+
@worker.shutdown #if Resque.size(:async_queue) == 0
|
107
|
+
end
|
108
|
+
|
109
|
+
# O(1)
|
110
|
+
(now - start).should be_within(DELAY*2).of(DELAY)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
metadata
ADDED
@@ -0,0 +1,267 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resque-kalashnikov
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Vlad Bokov
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
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: resque
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.23.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: 1.23.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: redis
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>'
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.0.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: 3.0.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: em-http-request
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
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: em-synchrony
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :runtime
|
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: em-hiredis
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :runtime
|
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
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rack-test
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: webmock
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rspec
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
description: Handles your HTTP requests in background in non-blocking way using Resque
|
159
|
+
worker
|
160
|
+
email:
|
161
|
+
- bokov.vlad@gmail.com
|
162
|
+
executables: []
|
163
|
+
extensions: []
|
164
|
+
extra_rdoc_files: []
|
165
|
+
files:
|
166
|
+
- .gitignore
|
167
|
+
- .rspec
|
168
|
+
- .travis.yml
|
169
|
+
- Gemfile
|
170
|
+
- LICENSE.txt
|
171
|
+
- README.md
|
172
|
+
- Rakefile
|
173
|
+
- demo/.gitignore
|
174
|
+
- demo/Gemfile
|
175
|
+
- demo/README.rdoc
|
176
|
+
- demo/Rakefile
|
177
|
+
- demo/app/assets/images/rails.png
|
178
|
+
- demo/app/assets/javascripts/application.js
|
179
|
+
- demo/app/assets/stylesheets/application.css
|
180
|
+
- demo/app/controllers/application_controller.rb
|
181
|
+
- demo/app/controllers/test_controller.rb
|
182
|
+
- demo/app/helpers/application_helper.rb
|
183
|
+
- demo/app/mailers/.gitkeep
|
184
|
+
- demo/app/models/.gitkeep
|
185
|
+
- demo/app/workers/slow_http_request.rb
|
186
|
+
- demo/config.ru
|
187
|
+
- demo/config/application.rb
|
188
|
+
- demo/config/boot.rb
|
189
|
+
- demo/config/environment.rb
|
190
|
+
- demo/config/environments/development.rb
|
191
|
+
- demo/config/environments/production.rb
|
192
|
+
- demo/config/environments/test.rb
|
193
|
+
- demo/config/initializers/backtrace_silencers.rb
|
194
|
+
- demo/config/initializers/inflections.rb
|
195
|
+
- demo/config/initializers/mime_types.rb
|
196
|
+
- demo/config/initializers/secret_token.rb
|
197
|
+
- demo/config/initializers/session_store.rb
|
198
|
+
- demo/config/initializers/wrap_parameters.rb
|
199
|
+
- demo/config/locales/en.yml
|
200
|
+
- demo/config/routes.rb
|
201
|
+
- demo/db/seeds.rb
|
202
|
+
- demo/lib/assets/.gitkeep
|
203
|
+
- demo/lib/tasks/.gitkeep
|
204
|
+
- demo/log/.gitkeep
|
205
|
+
- demo/public/404.html
|
206
|
+
- demo/public/422.html
|
207
|
+
- demo/public/500.html
|
208
|
+
- demo/public/favicon.ico
|
209
|
+
- demo/public/index.html
|
210
|
+
- demo/public/robots.txt
|
211
|
+
- demo/script/rails
|
212
|
+
- demo/script/resque_async.rb
|
213
|
+
- demo/vendor/assets/javascripts/.gitkeep
|
214
|
+
- demo/vendor/assets/stylesheets/.gitkeep
|
215
|
+
- demo/vendor/plugins/.gitkeep
|
216
|
+
- demo/zeus.json
|
217
|
+
- lib/event_machine/forced_stop.rb
|
218
|
+
- lib/resque/catridge.rb
|
219
|
+
- lib/resque/plugins/resque_kalashnikov/resque_kalashnikov.rb
|
220
|
+
- lib/resque_kalashnikov.rb
|
221
|
+
- lib/resque_kalashnikov/delegation.rb
|
222
|
+
- lib/resque_kalashnikov/http_request.rb
|
223
|
+
- lib/resque_kalashnikov/railtie.rb
|
224
|
+
- lib/resque_kalashnikov/server.rb
|
225
|
+
- lib/resque_kalashnikov/server/views/catridges.erb
|
226
|
+
- lib/resque_kalashnikov/version.rb
|
227
|
+
- lib/tasks.rb
|
228
|
+
- resque-kalashnikov.gemspec
|
229
|
+
- screenshot.png
|
230
|
+
- spec/catridge_spec.rb
|
231
|
+
- spec/http_request_spec.rb
|
232
|
+
- spec/server_spec.rb
|
233
|
+
- spec/spec_helper.rb
|
234
|
+
- spec/support/stub_server.rb
|
235
|
+
- spec/worker_spec.rb
|
236
|
+
- tasks/resque_kalashnikov.rake
|
237
|
+
homepage: ''
|
238
|
+
licenses: []
|
239
|
+
post_install_message:
|
240
|
+
rdoc_options: []
|
241
|
+
require_paths:
|
242
|
+
- lib
|
243
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
244
|
+
none: false
|
245
|
+
requirements:
|
246
|
+
- - ! '>='
|
247
|
+
- !ruby/object:Gem::Version
|
248
|
+
version: '0'
|
249
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
250
|
+
none: false
|
251
|
+
requirements:
|
252
|
+
- - ! '>='
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: '0'
|
255
|
+
requirements: []
|
256
|
+
rubyforge_project:
|
257
|
+
rubygems_version: 1.8.24
|
258
|
+
signing_key:
|
259
|
+
specification_version: 3
|
260
|
+
summary: This is awesome
|
261
|
+
test_files:
|
262
|
+
- spec/catridge_spec.rb
|
263
|
+
- spec/http_request_spec.rb
|
264
|
+
- spec/server_spec.rb
|
265
|
+
- spec/spec_helper.rb
|
266
|
+
- spec/support/stub_server.rb
|
267
|
+
- spec/worker_spec.rb
|