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,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
|