何百万もの URL のバッチ処理を担当する rake タスクがあります。このプロセスには非常に時間がかかるため、処理しようとしている URL が無効になっていることに気付くことがあります (404、サイトのダウンなど)。
私が最初にこれを書いたとき、処理中に継続的にダウンするサイトは基本的に 1 つだけだったので、私の解決策は を使用しopen-uri
、生成された例外をレスキューし、少し待ってから再試行することでした。
データセットが小さかったときはこれでうまくいきましたが、今では時間がかかりすぎて、URL がなくなって 404 が生成されることがわかりました。
404 のケースを使用すると、これが発生すると、スクリプトはそこに留まり、無限にループします。明らかに悪いことです。
ページが正常にロードされない場合はどのように処理すればよいですか? さらに重要なことに、これは私が構築した「スタック」にどのように収まりますか?
私はこれと Rails にかなり慣れていないので、この設計でどこが間違っていたのかについての意見を歓迎します!
これは、私が持っているものを示す匿名化されたコードです。
MyHelperModule を呼び出す rake タスク:
# lib/tasks/my_app_tasks.rake
namespace :my_app do
desc "Batch processes some stuff @ a later time."
task :process_the_batch => :environment do
# The dataset being processed
# is millions of rows so this is a big job
# and should be done in batches!
MyModel.where(some_thing: nil).find_in_batches do |my_models|
MyHelperModule.do_the_process my_models: my_models
end
end
end
end
MyHelperModule はmy_models
、ActiveRecord を受け入れてさらに処理を行います。それは呼び出しますSomeClass
:
# lib/my_helper_module.rb
module MyHelperModule
def self.do_the_process(args = {})
my_models = args[:my_models]
# Parallel.each(my_models, :in_processes => 5) do |my_model|
my_models.each do |my_model|
# Reconnect to prevent errors with Postgres
ActiveRecord::Base.connection.reconnect!
# Do some active record stuff
some_var = SomeClass.new(my_model.id)
# Do something super interesting,
# fun,
# AND sexy with my_model
end
end
end
SomeClass
経由で Web にアクセスしWebpageHelper
、ページを処理します。
# lib/some_class.rb
require_relative 'webpage_helper'
class SomeClass
attr_accessor :some_data
def initialize(arg)
doc = WebpageHelper.get_doc("http://somesite.com/#{arg}")
# do more stuff
end
end
WebpageHelper
404の場合、例外がキャッチされ、無限ループが開始される場所です。
# lib/webpage_helper.rb
require 'nokogiri'
require 'open-uri'
class WebpageHelper
def self.get_doc(url)
begin
page_content = open(url).read
# do more stuff
rescue Exception => ex
puts "Failed at #{Time.now}"
puts "Error: #{ex}"
puts "URL: " + url
puts "Retrying... Attempt #: #{attempts.to_s}"
attempts = attempts + 1
sleep(10)
retry
end
end
end