add retry monkey patch for mechanize
This commit is contained in:
57
config/initializers/mechanize_patch.rb
Normal file
57
config/initializers/mechanize_patch.rb
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
require 'mechanize'
|
||||||
|
|
||||||
|
if Rails.env.test?
|
||||||
|
class Mechanize::HTTP::Agent
|
||||||
|
MAX_RESET_RETRIES = 10
|
||||||
|
|
||||||
|
# We need to replace the core Mechanize HTTP method:
|
||||||
|
#
|
||||||
|
# Mechanize::HTTP::Agent#fetch
|
||||||
|
#
|
||||||
|
# with a wrapper that handles the infamous "too many connection resets"
|
||||||
|
# Mechanize bug that is described here:
|
||||||
|
#
|
||||||
|
# https://github.com/sparklemotion/mechanize/issues/123
|
||||||
|
#
|
||||||
|
# The wrapper shuts down the persistent HTTP connection when it fails with
|
||||||
|
# this error, and simply tries again. In practice, this only ever needs to
|
||||||
|
# be retried once, but I am going to let it retry a few times
|
||||||
|
# (MAX_RESET_RETRIES), just in case.
|
||||||
|
#
|
||||||
|
def fetch_with_retry(
|
||||||
|
uri,
|
||||||
|
method = :get,
|
||||||
|
headers = {},
|
||||||
|
params = [],
|
||||||
|
referer = current_page,
|
||||||
|
redirects = 0
|
||||||
|
)
|
||||||
|
action = "#{method.to_s.upcase} #{uri.to_s}"
|
||||||
|
retry_count = 0
|
||||||
|
|
||||||
|
begin
|
||||||
|
fetch_without_retry(uri, method, headers, params, referer, redirects)
|
||||||
|
rescue Net::HTTP::Persistent::Error => e
|
||||||
|
# Pass on any other type of error.
|
||||||
|
raise unless e.message =~ /too many connection resets/
|
||||||
|
|
||||||
|
# Pass on the error if we've tried too many times.
|
||||||
|
if retry_count >= MAX_RESET_RETRIES
|
||||||
|
puts "**** WARN: Mechanize retried connection reset #{MAX_RESET_RETRIES} times and never succeeded: #{action}"
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
|
||||||
|
# Otherwise, shutdown the persistent HTTP connection and try again.
|
||||||
|
puts "**** WARN: Mechanize retrying connection reset error: #{action}"
|
||||||
|
retry_count += 1
|
||||||
|
self.http.shutdown
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Alias so #fetch actually uses our new #fetch_with_retry to wrap the
|
||||||
|
# old one aliased as #fetch_without_retry.
|
||||||
|
alias_method :fetch_without_retry, :fetch
|
||||||
|
alias_method :fetch, :fetch_with_retry
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2,13 +2,6 @@ require 'test_helper'
|
|||||||
|
|
||||||
module Downloads
|
module Downloads
|
||||||
class PixivTest < ActiveSupport::TestCase
|
class PixivTest < ActiveSupport::TestCase
|
||||||
def teardown
|
|
||||||
super
|
|
||||||
|
|
||||||
# need to reset the connection
|
|
||||||
Sources::Strategies::Pixiv.new("http://www.pixiv.net").agent.shutdown
|
|
||||||
end
|
|
||||||
|
|
||||||
context "An ugoira site for pixiv" do
|
context "An ugoira site for pixiv" do
|
||||||
setup do
|
setup do
|
||||||
@download = Downloads::File.new("http://www.pixiv.net/member_illust.php?mode=medium&illust_id=62247364")
|
@download = Downloads::File.new("http://www.pixiv.net/member_illust.php?mode=medium&illust_id=62247364")
|
||||||
|
|||||||
@@ -8,13 +8,6 @@ module Sources
|
|||||||
@site
|
@site
|
||||||
end
|
end
|
||||||
|
|
||||||
def teardown
|
|
||||||
super
|
|
||||||
|
|
||||||
# need to reset the connection
|
|
||||||
Sources::Strategies::Pixiv.new("http://www.pixiv.net").agent.shutdown
|
|
||||||
end
|
|
||||||
|
|
||||||
context "in all cases" do
|
context "in all cases" do
|
||||||
context "A touch page" do
|
context "A touch page" do
|
||||||
setup do
|
setup do
|
||||||
|
|||||||
Reference in New Issue
Block a user