resque-kalashnikov 1.1.0
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/.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,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'em-synchrony'
|
3
|
+
|
4
|
+
require "resque_kalashnikov/delegation"
|
5
|
+
require 'resque/worker'
|
6
|
+
require 'resque/catridge'
|
7
|
+
require "resque/plugins/resque_kalashnikov/resque_kalashnikov"
|
8
|
+
require "event_machine/forced_stop"
|
9
|
+
require "resque_kalashnikov/http_request"
|
10
|
+
require "resque_kalashnikov/railtie" if defined?(Rails)
|
11
|
+
|
12
|
+
module ResqueKalashnikov
|
13
|
+
delegate :stats, :misfire_codes, :misfire_stats, :misfire_stats_reset, :reset_stats, to: Resque::Catridge, prefix: 'kalashnikov'
|
14
|
+
end
|
15
|
+
|
16
|
+
Resque.extend ResqueKalashnikov
|
17
|
+
Resque::Worker.send(:include, Resque::Plugins::ResqueKalashnikov)
|
@@ -0,0 +1,153 @@
|
|
1
|
+
class Module
|
2
|
+
# Provides a delegate class method to easily expose contained objects' methods
|
3
|
+
# as your own. Pass one or more methods (specified as symbols or strings)
|
4
|
+
# and the name of the target object via the <tt>:to</tt> option (also a symbol
|
5
|
+
# or string). At least one method and the <tt>:to</tt> option are required.
|
6
|
+
#
|
7
|
+
# Delegation is particularly useful with Active Record associations:
|
8
|
+
#
|
9
|
+
# class Greeter < ActiveRecord::Base
|
10
|
+
# def hello
|
11
|
+
# "hello"
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# def goodbye
|
15
|
+
# "goodbye"
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# class Foo < ActiveRecord::Base
|
20
|
+
# belongs_to :greeter
|
21
|
+
# delegate :hello, :to => :greeter
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Foo.new.hello # => "hello"
|
25
|
+
# Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
|
26
|
+
#
|
27
|
+
# Multiple delegates to the same target are allowed:
|
28
|
+
#
|
29
|
+
# class Foo < ActiveRecord::Base
|
30
|
+
# belongs_to :greeter
|
31
|
+
# delegate :hello, :goodbye, :to => :greeter
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# Foo.new.goodbye # => "goodbye"
|
35
|
+
#
|
36
|
+
# Methods can be delegated to instance variables, class variables, or constants
|
37
|
+
# by providing them as a symbols:
|
38
|
+
#
|
39
|
+
# class Foo
|
40
|
+
# CONSTANT_ARRAY = [0,1,2,3]
|
41
|
+
# @@class_array = [4,5,6,7]
|
42
|
+
#
|
43
|
+
# def initialize
|
44
|
+
# @instance_array = [8,9,10,11]
|
45
|
+
# end
|
46
|
+
# delegate :sum, :to => :CONSTANT_ARRAY
|
47
|
+
# delegate :min, :to => :@@class_array
|
48
|
+
# delegate :max, :to => :@instance_array
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# Foo.new.sum # => 6
|
52
|
+
# Foo.new.min # => 4
|
53
|
+
# Foo.new.max # => 11
|
54
|
+
#
|
55
|
+
# Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
|
56
|
+
# is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
|
57
|
+
# delegated to.
|
58
|
+
#
|
59
|
+
# Person = Struct.new(:name, :address)
|
60
|
+
#
|
61
|
+
# class Invoice < Struct.new(:client)
|
62
|
+
# delegate :name, :address, :to => :client, :prefix => true
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# john_doe = Person.new("John Doe", "Vimmersvej 13")
|
66
|
+
# invoice = Invoice.new(john_doe)
|
67
|
+
# invoice.client_name # => "John Doe"
|
68
|
+
# invoice.client_address # => "Vimmersvej 13"
|
69
|
+
#
|
70
|
+
# It is also possible to supply a custom prefix.
|
71
|
+
#
|
72
|
+
# class Invoice < Struct.new(:client)
|
73
|
+
# delegate :name, :address, :to => :client, :prefix => :customer
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# invoice = Invoice.new(john_doe)
|
77
|
+
# invoice.customer_name # => "John Doe"
|
78
|
+
# invoice.customer_address # => "Vimmersvej 13"
|
79
|
+
#
|
80
|
+
# If the delegate object is +nil+ an exception is raised, and that happens
|
81
|
+
# no matter whether +nil+ responds to the delegated method. You can get a
|
82
|
+
# +nil+ instead with the +:allow_nil+ option.
|
83
|
+
#
|
84
|
+
# class Foo
|
85
|
+
# attr_accessor :bar
|
86
|
+
# def initialize(bar = nil)
|
87
|
+
# @bar = bar
|
88
|
+
# end
|
89
|
+
# delegate :zoo, :to => :bar
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
|
93
|
+
#
|
94
|
+
# class Foo
|
95
|
+
# attr_accessor :bar
|
96
|
+
# def initialize(bar = nil)
|
97
|
+
# @bar = bar
|
98
|
+
# end
|
99
|
+
# delegate :zoo, :to => :bar, :allow_nil => true
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# Foo.new.zoo # returns nil
|
103
|
+
#
|
104
|
+
def delegate(*methods)
|
105
|
+
options = methods.pop
|
106
|
+
unless options.is_a?(Hash) && to = options[:to]
|
107
|
+
raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
|
108
|
+
end
|
109
|
+
prefix, to, allow_nil = options[:prefix], options[:to], options[:allow_nil]
|
110
|
+
|
111
|
+
if prefix == true && to.to_s =~ /^[^a-z_]/
|
112
|
+
raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
|
113
|
+
end
|
114
|
+
|
115
|
+
method_prefix =
|
116
|
+
if prefix
|
117
|
+
"#{prefix == true ? to : prefix}_"
|
118
|
+
else
|
119
|
+
''
|
120
|
+
end
|
121
|
+
|
122
|
+
file, line = caller.first.split(':', 2)
|
123
|
+
line = line.to_i
|
124
|
+
|
125
|
+
methods.each do |method|
|
126
|
+
method = method.to_s
|
127
|
+
|
128
|
+
if allow_nil
|
129
|
+
module_eval(<<-EOS, file, line - 2)
|
130
|
+
def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
|
131
|
+
if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
|
132
|
+
#{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block)
|
133
|
+
end # end
|
134
|
+
end # end
|
135
|
+
EOS
|
136
|
+
else
|
137
|
+
exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
|
138
|
+
|
139
|
+
module_eval(<<-EOS, file, line - 1)
|
140
|
+
def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
|
141
|
+
#{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block)
|
142
|
+
rescue NoMethodError # rescue NoMethodError
|
143
|
+
if #{to}.nil? # if client.nil?
|
144
|
+
#{exception} # # add helpful message to the exception
|
145
|
+
else # else
|
146
|
+
raise # raise
|
147
|
+
end # end
|
148
|
+
end # end
|
149
|
+
EOS
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "em-synchrony/em-http"
|
2
|
+
|
3
|
+
module ResqueKalashnikov
|
4
|
+
class HttpRequest
|
5
|
+
attr_accessor :url, :http_method, :opts
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
case args.size
|
9
|
+
when 1 then @url = args[0]
|
10
|
+
when 2 then @url, @opts = args
|
11
|
+
when 3 then @url, @http_method, @opts = args
|
12
|
+
else
|
13
|
+
raise "insufficient params in #{self.class}: args=#{args}"
|
14
|
+
end
|
15
|
+
@http_method ||= 'get'
|
16
|
+
@opts ||= {}
|
17
|
+
@http_method.downcase!
|
18
|
+
end
|
19
|
+
|
20
|
+
# This method is invoked inside EM
|
21
|
+
# no blocking calls, please
|
22
|
+
def handle http
|
23
|
+
Resque::Catridge.new(self, http)
|
24
|
+
end
|
25
|
+
|
26
|
+
def retry_limit
|
27
|
+
instance_variable_get(:@retry_limit) || 2
|
28
|
+
end
|
29
|
+
|
30
|
+
def perform
|
31
|
+
catrige = handle http_request
|
32
|
+
reload if catrige.reload? && catrige.retries < retry_limit
|
33
|
+
http_request.response
|
34
|
+
end
|
35
|
+
|
36
|
+
def reload_opts
|
37
|
+
opts
|
38
|
+
end
|
39
|
+
|
40
|
+
def http_method
|
41
|
+
valid_methods.include?(@http_method) ? @http_method : 'get'
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def reload
|
47
|
+
Resque.enqueue self.class, url, http_method, reload_opts
|
48
|
+
end
|
49
|
+
|
50
|
+
def http_request
|
51
|
+
EM::HttpRequest.new(url).send http_method, query: opts
|
52
|
+
end
|
53
|
+
|
54
|
+
def valid_methods
|
55
|
+
['get', 'post', 'head', 'delete', 'put', 'options', 'patch']
|
56
|
+
end
|
57
|
+
|
58
|
+
class << self
|
59
|
+
def perform(*args)
|
60
|
+
new(*args).perform
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'resque_kalashnikov'
|
2
|
+
require 'resque/server'
|
3
|
+
|
4
|
+
module ResqueKalashnikov
|
5
|
+
|
6
|
+
module Server
|
7
|
+
|
8
|
+
def render_erb(view)
|
9
|
+
erb File.read(File.join(File.dirname(__FILE__), view))
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
get "/kalashnikov" do
|
15
|
+
render_erb 'server/views/catridges.erb'
|
16
|
+
end
|
17
|
+
|
18
|
+
post "/kalashnikov/retry/:status" do
|
19
|
+
status = params[:status]
|
20
|
+
klass_name, args = Resque.decode Base64.decode64 params[:request_key]
|
21
|
+
klass = Resque::Job.constantize klass_name
|
22
|
+
queue = Resque.queue_from_class(klass)
|
23
|
+
redis = Redis.connect
|
24
|
+
redis.rpush "resque:queue:#{queue}", Resque.encode(:class => klass_name, :args => args)
|
25
|
+
sleep 3 # FIXME: if refreshed immediately - no effect seen - instead, can be polled
|
26
|
+
redirect u('/kalashnikov')
|
27
|
+
end
|
28
|
+
|
29
|
+
post "/kalashnikov/reset/:status" do
|
30
|
+
status = params[:status]
|
31
|
+
request_key = Base64.decode64 params[:request_key]
|
32
|
+
redis = Redis.connect
|
33
|
+
redis.hset "resque:kalashnikov:misfires:#{status}", request_key, 0
|
34
|
+
redirect u('/kalashnikov')
|
35
|
+
end
|
36
|
+
|
37
|
+
get "/kalashnikov/reset_stats" do
|
38
|
+
Resque::Catridge.reset_stats
|
39
|
+
redirect u('/kalashnikov')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Resque::Server.tabs << 'Kalashnikov'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Resque::Server.class_eval do
|
49
|
+
include ResqueKalashnikov::Server
|
50
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<% statuses = resque.kalashnikov_stats %>
|
2
|
+
|
3
|
+
<h1 class='wi'>Kalashnikov</h1>
|
4
|
+
<p class='intro'>The list below contains statistics of Kalashnikov</p>
|
5
|
+
<table>
|
6
|
+
<tr>
|
7
|
+
<th>HTTP code</th>
|
8
|
+
<th>Jobs done</th>
|
9
|
+
</tr>
|
10
|
+
<% statuses.sort.each do |status, count| %>
|
11
|
+
<tr>
|
12
|
+
<td class='status'><%= status %></td>
|
13
|
+
<td class='size'><%= count %></td>
|
14
|
+
</tr>
|
15
|
+
<% end %>
|
16
|
+
</table>
|
17
|
+
|
18
|
+
<% resque.kalashnikov_misfire_codes.each do |misfire_stats_key| %>
|
19
|
+
<% status = misfire_stats_key.split(':').last %>
|
20
|
+
<h1 class='wi'>Error code: <%= status %></h1>
|
21
|
+
<table>
|
22
|
+
<tr>
|
23
|
+
<th>Job</th>
|
24
|
+
<th>HTTP</th>
|
25
|
+
<th>URL</th>
|
26
|
+
<th>Options</th>
|
27
|
+
<th>Retries</th>
|
28
|
+
<th>Retry</th>
|
29
|
+
<th>Reset retries</th>
|
30
|
+
</tr>
|
31
|
+
<% resque.kalashnikov_misfire_stats(misfire_stats_key).sort_by { |k,v| v } .reverse.each do |misfire_json, count| %>
|
32
|
+
<tr>
|
33
|
+
<% job, payload = resque.decode misfire_json %>
|
34
|
+
<% url, http_method, options = payload %>
|
35
|
+
<td class='job'><%= job %></td>
|
36
|
+
<td class='http_method'><%= http_method.upcase %></td>
|
37
|
+
<td class='url'><a href="<%= url %>"><%= url %></a></td>
|
38
|
+
<td class='options'><%= options %></td>
|
39
|
+
<td class='size'><%= count %></td>
|
40
|
+
<td class='url'>
|
41
|
+
<form method="POST" action="<%= u %Q{kalashnikov/retry/#{status}} %>" >
|
42
|
+
<input name="request_key" type="hidden" value="<%= Base64.encode64 misfire_json %>" />
|
43
|
+
<input type='submit' name='' value='Retry' />
|
44
|
+
</form>
|
45
|
+
</td>
|
46
|
+
<td class='url'>
|
47
|
+
<form method="POST" action="<%= u %Q{kalashnikov/reset/#{status}} %>" >
|
48
|
+
<input name="request_key" type="hidden" value="<%= Base64.encode64 misfire_json %>" />
|
49
|
+
<input type='submit' name='' value='Reset' />
|
50
|
+
</form>
|
51
|
+
</td>
|
52
|
+
</tr>
|
53
|
+
<% end %>
|
54
|
+
</table>
|
55
|
+
<% end %>
|
56
|
+
|
57
|
+
<a href="<%= u %Q{kalashnikov/reset_stats} %>">Reset Kalashnikov statistics</a>
|
data/lib/tasks.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
namespace :resque do
|
2
|
+
|
3
|
+
desc "Fire Kalashnikov"
|
4
|
+
task :fire do
|
5
|
+
|
6
|
+
require 'resque'
|
7
|
+
require 'em-synchrony'
|
8
|
+
require 'em-synchrony/em-hiredis'
|
9
|
+
require 'resque_kalashnikov'
|
10
|
+
|
11
|
+
queues = (ENV['QUEUES'] || ENV['QUEUE']).to_s.split(',')
|
12
|
+
|
13
|
+
# FIXME: cannot start with clean redis
|
14
|
+
abort "QUEUE env var cannot be '*', please, list your queues" if queues.include? '*'
|
15
|
+
redis = Redis.connect
|
16
|
+
queues.each { |queue| redis.sadd "resque:queues", queue }
|
17
|
+
|
18
|
+
|
19
|
+
if defined?(Rails) && Rails.respond_to?(:application)
|
20
|
+
Rails.application.eager_load!
|
21
|
+
end
|
22
|
+
|
23
|
+
worker = Resque::Worker.new(*queues)
|
24
|
+
#worker.verbose = true
|
25
|
+
|
26
|
+
EM.synchrony do
|
27
|
+
Resque.redis = EM::Synchrony::ConnectionPool.new(size: 100) do
|
28
|
+
EM::Hiredis.connect
|
29
|
+
end
|
30
|
+
['TERM', 'INT', 'QUIT'].each { |signal| trap(signal) { EM.stop } }
|
31
|
+
worker.work(0)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'resque_kalashnikov/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "resque-kalashnikov"
|
8
|
+
gem.version = ResqueKalashnikov::VERSION
|
9
|
+
gem.authors = ["Vlad Bokov"]
|
10
|
+
gem.email = ["bokov.vlad@gmail.com"]
|
11
|
+
gem.summary = %q{This is awesome}
|
12
|
+
gem.description = %q{Handles your HTTP requests in background in non-blocking way using Resque worker}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency('rake')
|
21
|
+
gem.add_dependency('resque', '~> 1.23.0')
|
22
|
+
gem.add_dependency('redis', '> 3.0.0')
|
23
|
+
gem.add_dependency('em-http-request')
|
24
|
+
gem.add_dependency('em-synchrony')
|
25
|
+
gem.add_dependency('em-hiredis')
|
26
|
+
|
27
|
+
gem.add_development_dependency('rack-test')
|
28
|
+
gem.add_development_dependency('webmock')
|
29
|
+
gem.add_development_dependency('rspec')
|
30
|
+
end
|
data/screenshot.png
ADDED
Binary file
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Resque::Catridge do
|
4
|
+
before do
|
5
|
+
@fake_redis = double
|
6
|
+
@fake_redis.stub(:hget)
|
7
|
+
@fake_redis.stub(:rpush)
|
8
|
+
@fake_redis.stub(:hincrby)
|
9
|
+
@fake_redis.stub(:keys)
|
10
|
+
Resque::Catridge.stub(:redis).and_return(@fake_redis)
|
11
|
+
end
|
12
|
+
|
13
|
+
def fake_response_with_status(status)
|
14
|
+
response = double
|
15
|
+
response.stub_chain(:response_header, :status).and_return(status)
|
16
|
+
response
|
17
|
+
end
|
18
|
+
|
19
|
+
def fake_request
|
20
|
+
request = double
|
21
|
+
request.stub(:url).and_return 'some-url'
|
22
|
+
request.stub(:http_method).and_return 'get'
|
23
|
+
request.stub(:reload_opts).and_return 'some-opts'
|
24
|
+
request
|
25
|
+
end
|
26
|
+
|
27
|
+
def build(response)
|
28
|
+
Resque::Catridge.new fake_request, response
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'forces no reload on 200' do
|
32
|
+
build(fake_response_with_status 200).reload?.should be_false
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'forces 404 for reload' do
|
36
|
+
build(fake_response_with_status 404).reload?.should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'forces 500 for reload' do
|
40
|
+
build(fake_response_with_status 500).reload?.should be_true
|
41
|
+
end
|
42
|
+
end
|