I have a rails app on heroku that uses Resque.enqueu to schedule background jobs using Redis and redistogo.
Jobs used to work normally but I notice now that they have all been failing for some time (a few weeks, 100% of jobs).
The error I get:
Exception Errno::ETIMEDOUT Error Connection timed out - connect(2)
And the stack trace:
> /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/http.rb:878:in `initialize'
> /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/http.rb:878:in `open'
> /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/http.rb:878:in `block in
> connect' /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/timeout.rb:52:in
> `timeout' /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/http.rb:877:in
> `connect' /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/http.rb:862:in
> `do_start' /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/http.rb:851:in
> `start' /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/http.rb:1373:in
> `request' /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/net/http.rb:1131:in
> `get'
> /app/vendor/bundle/ruby/2.0.0/gems/activeresource-4.0.0/lib/active_resource/connection.rb:121:in `block in request'
> /app/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.1/lib/active_support/notifications.rb:164:in
> `block in instrument'
> /app/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.1/lib/active_support/notifications/instrumenter.rb:20:in
> `instrument'
> /app/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.1/lib/active_support/notifications.rb:164:in
> `instrument'
> /app/vendor/bundle/ruby/2.0.0/gems/activeresource-4.0.0/lib/active_resource/connection.rb:118:in `request'
> /app/vendor/bundle/ruby/2.0.0/gems/shopify_api-4.0.6/lib/active_resource/connection_ext.rb:13:in `request_with_detailed_log_subscriber'
> /app/vendor/bundle/ruby/2.0.0/gems/activeresource-4.0.0/lib/active_resource/connection.rb:82:in
> `block in get'
> /app/vendor/bundle/ruby/2.0.0/gems/activeresource-4.0.0/lib/active_resource/connection.rb:216:in `with_auth'
> /app/vendor/bundle/ruby/2.0.0/gems/activeresource-4.0.0/lib/active_resource/connection.rb:82:in
> `get'
> /app/vendor/bundle/ruby/2.0.0/gems/activeresource-4.0.0/lib/active_resource/custom_methods.rb:57:in
> `get'
> /app/vendor/bundle/ruby/2.0.0/gems/shopify_api-4.0.6/lib/shopify_api/countable.rb:4:in
> `count' /app/app/models/shop.rb:263:in `unscanned_customers'
> /app/app/models/shop.rb:230:in `shopify_customers'
> /app/app/models/shop.rb:144:in `bulk_scan'
> /app/app/workers/bulk_scanner.rb:16:in `perform'
I was thinking maybe it is something to do with not connecting to Redis or redistogo properly. Here are the relevant initializer code that I have:
resque.rb:
Resque.redis = RedisConnection.connection
redis_connection.rb:
class RedisConnection
def self.close
connection.quit
end
def self.connection
#connection ||= new_connection
end
def self.new_connection
uri = URI.parse(ENV['REDISTOGO_URL'] || 'redis://localhost:6379/')
Redis.new(host: uri.host,
port: uri.port,
password: uri.password,
thread_safe: true,
:timeout => 1)
end
end
If I call Resque.redis or #connection in my app, it returns a Redis instance. What else would be causing this connection error? Where can I troubleshoot?
Looking at the Backtrace, could it be a Shopify API connection timeout?
It looks like unscanned_customers is a supposed to be a countable Shopify collection and the problem occurs when an attempt to retrieve the customer is made.
I would start my debugging here:
> 'count' /app/app/models/shop.rb:263:in
'unscanned_customers'
Additionally, I would attempt to connect to Shopify from the server with a private app API key and password:
shop_url = "https://#{API_KEY}:#{PASSWORD}#SHOP_NAME.myshopify.com/admin"
ShopifyAPI::Base.site = shop_url
Refer to the Shopify API for more details if needed Shopify API Readme
It will help isolate the connection issue.
Cheers.
Related
I'm setting up a background task with sidekiq and redis. Have it working completely fine in development, but when testing on staging site I get:
NameError: uninitialized constant InviteWorker::User
/controllers/users_controller.rb
class UsersController < ApplicationController
def invite
params[:user] ? #user = User.where(:referral_code => params[:user])[0] : #user = User.find_by_email(cookies[:h_email])
user_id = #user.id
content = params[:body]
emails = params[:email].split(',')
total_emails = emails.length
user_email = #user.email
referral_code = #user.referral_code
cloudsponge_emails = params[:count_cloudsponge]
tracked_count = false
InviteWorker.perform_async(content, emails, total_emails, user_email, referral_code, cloudsponge_emails, tracked_count, user_id)
redirect_to :back
end
/app/workers/invite_worker.rb
class InviteWorker
include Sidekiq::Worker
def perform(content, emails, total_emails, user_email, referral_code, cloudsponge_emails, tracked_count, user_id)
user = User.find(user_id)
emails.each_with_index do |email,index|
email = email.gsub(/\s+/, '')
if email.include? '<'
email = email.split('<')[1].split('>')[0]
end
if User.where(:email => email).empty? && EmailInvite.where('created_at >= ?', Time.now.beginning_of_day).where(:email => email).empty? && User.new.verify_email(email)
UserMailer.invite_email(content, email, user_email, referral_code).deliver_now
if index == 0 || tracked_count == false
EmailInvite.create(:user => user, :email => email, :count => total_emails)
tracked_count = true
else
EmailInvite.create(:user => user, :email => email)
end
end
end
end
end
/config/application.rb
config.autoload_paths += %W(
#{config.root}/app/workers
#{config.root}/lib
)
config.eager_load_paths += %W(
#{config.root}/app/workers
#{config.root}/lib
)
Procfile
web: bundle exec puma -C ./config/puma.rb
worker: bundle exec sidekiq -e $RACK_ENV -r ./config/sidekiq.rb -c ${SIDEKIQ_CONCURRENCY:-5}
Edit - error message provided:
4 TID-u31nw InviteWorker JID-ea609b6557e45a4d299dcde7 INFO: start
4 TID-u31nw InviteWorker JID-ea609b6557e45a4d299dcde7 INFO: fail: 0.002 sec
4 TID-u31nw WARN: {"context":"Job raised exception","job":{"class":"InviteWorker","args":["Hey, join me and sign up!",["email#umd.edu"],1,"email#gmail.com","68QBZ","0",false,2945],"retry":true,"queue":"default","jid":"ea609b6557e45a4d299dcde7","created_at":1531780015.902798,"enqueued_at":1531780015.9035575},"jobstr":"{\"class\":\"InviteWorker\",\"args\":[\"Hey, join me and sign up!\",[\"email#umd.edu\"],1,\"email#gmail.com\",\"68QBZ\",\"0\",false,2945],\"retry\":true,\"queue\":\"default\",\"jid\":\"ea609b6557e45a4d299dcde7\",\"created_at\":1531780015.902798,\"enqueued_at\":1531780015.9035575}"}
4 TID-u31nw WARN: NameError: uninitialized constant InviteWorker::User
4 TID-u31nw WARN: /app/app/workers/invite_worker.rb:5:in `perform'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:187:in `execute_job'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:169:in `block (2 levels) in process'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/middleware/chain.rb:128:in `block in invoke'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/middleware/chain.rb:133:in `invoke'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:168:in `block in process'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:139:in `block (6 levels) in dispatch'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/job_retry.rb:98:in `local'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:138:in `block (5 levels) in dispatch'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq.rb:36:in `block in <module:Sidekiq>'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:134:in `block (4 levels) in dispatch'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:199:in `stats'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:129:in `block (3 levels) in dispatch'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/job_logger.rb:8:in `call'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:128:in `block (2 levels) in dispatch'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/job_retry.rb:73:in `global'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:127:in `block in dispatch'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/logging.rb:48:in `with_context'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/logging.rb:42:in `with_job_hash_context'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:126:in `dispatch'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:167:in `process'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:85:in `process_one'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:73:in `run'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/util.rb:16:in `watchdog'
/app/vendor/bundle/ruby/2.3.0/gems/sidekiq-5.1.3/lib/sidekiq/util.rb:25:in `block in safe_thread'
In my case, I just restarted Sidekiq on production and it fixed a problem: sudo service sidekiq restart
In my case problem was in 'namespace' parameter for redis in application.yml try to write it and reload redis, sidekiq and server
redis:
url: redis://localhost:6379/1
namespace: "some_namespace_name"
it has nothing to do with the eager_load or autoload paths. If you are using puma with many workers then you need to call these below the workers number in your config/puma.rb
workers 2
preload_app! #used when workers are more than 0
I”m using Rails 4.2.7 and I have several Tor gems installed.
gem 'tor'
gem 'tor_requests'
gem 'tor-privoxy'
gem 'net-telnet'
I started my Tor browser (running on Mac El Capitan) and I want to periodically (every 20th request) change the IP address of where my TOR web requests originate. So I tried this
agent = TorPrivoxy::Agent.new '127.0.0.1', '', {8118 => 9151} do |agent|
sleep 1
puts "New IP is #{agent.ip}"
end
However, this results in the below error. I’m confused about how else I need to configure things so that I can make the above work.
Error during processing: Failed to open TCP connection to 127.0.0.1:8118 (general SOCKS server failure)
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:882:in `rescue in block in connect'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:879:in `block in connect'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/timeout.rb:91:in `block in timeout'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/timeout.rb:101:in `timeout'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:878:in `connect'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:863:in `do_start'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:858:in `start'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/net-http-persistent-2.9.4/lib/net/http/persistent.rb:700:in `start'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/net-http-persistent-2.9.4/lib/net/http/persistent.rb:631:in `connection_for'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/net-http-persistent-2.9.4/lib/net/http/persistent.rb:994:in `request'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/mechanize-2.7.5/lib/mechanize/http/agent.rb:274:in `fetch'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/mechanize-2.7.5/lib/mechanize.rb:464:in `get'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/tor-privoxy-0.1.1/lib/tor-privoxy/agent.rb:38:in `ip'
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:57:in `block in get_content'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/tor-privoxy-0.1.1/lib/tor-privoxy/agent.rb:11:in `initialize'
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:55:in `new'
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:55:in `rescue in get_content'
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:50:in `get_content'
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:14:in `get_url'
/Users/davea/Documents/workspace/myproject/app/services/onlinerr_race_finder_service.rb:41:in `get_race_list'
/Users/davea/Documents/workspace/myproject/app/services/abstract_race_finder_service.rb:26:in `process_data'
/Users/davea/Documents/workspace/myproject/app/services/run_crawlers_service.rb:18:in `block in run_all_crawlers'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/relation/delegation.rb:46:in `each'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/relation/delegation.rb:46:in `each'
/Users/davea/Documents/workspace/myproject/app/services/run_crawlers_service.rb:5:in `run_all_crawlers'
(irb):2:in `irb_binding'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb/workspace.rb:87:in `eval'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb/workspace.rb:87:in `evaluate'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb/context.rb:380:in `evaluate'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb.rb:489:in `block (2 levels) in eval_input'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb.rb:623:in `signal_status'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb.rb:486:in `block in eval_input'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb/ruby-lex.rb:246:in `block (2 levels) in each_top_level_statement'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb/ruby-lex.rb:232:in `loop'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb/ruby-lex.rb:232:in `block in each_top_level_statement'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb/ruby-lex.rb:231:in `catch'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb/ruby-lex.rb:231:in `each_top_level_statement'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb.rb:485:in `eval_input'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb.rb:395:in `block in start'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb.rb:394:in `catch'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/irb.rb:394:in `start'
How do I programmatically force an IP address change using Ruby/Tor?
Edit:Here is what I included in my helper file and below is the error that results
require 'rubygems'
$:.unshift "./tor/lib"
require 'tor'
…
cookie_file = '/Users/davea/Library/Application Support/TorBrowser-Data/Tor/control_auth_cookie'
file = File.open(cookie_file, 'rb')
cookie = file.read # read contents of auth cookie to string
file.close
Tor::Controller.connect(:port => 9150, :cookie => cookie) do |tor|
tor.signal('NEWNYM') # send NEWNYM signal (gets new IP)
end
The error that results in the rails console …
Error during processing: undefined method `signal' for #<Tor::Controller:0x007fe044b1e550>
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:87:in `block in get_content'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/tor-0.1.2/lib/tor/control.rb:38:in `connect'
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:86:in `rescue in get_content'
Edit 2:
After adding this to my Gemfile file
gem 'tor', :git => 'https://github.com/dryruby/tor.rb.git'
I ran the code above, and now got the error …
Error during processing: end of file reached
/Users/davea/.rvm/gems/ruby-2.3.0/bundler/gems/tor.rb-08e589d17196/lib/tor/control.rb:301:in `readline'
/Users/davea/.rvm/gems/ruby-2.3.0/bundler/gems/tor.rb-08e589d17196/lib/tor/control.rb:301:in `read_reply'
/Users/davea/.rvm/gems/ruby-2.3.0/bundler/gems/tor.rb-08e589d17196/lib/tor/control.rb:194:in `authenticate'
/Users/davea/.rvm/gems/ruby-2.3.0/bundler/gems/tor.rb-08e589d17196/lib/tor/control.rb:282:in `send_command'
/Users/davea/.rvm/gems/ruby-2.3.0/bundler/gems/tor.rb-08e589d17196/lib/tor/control.rb:269:in `signal'
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:90:in `block in get_content'
To change your IP in Tor, you need to connect directly to the controller (it uses a telnet-like line based command/response protocol.
It looks like you're trying to connect through Privoxy which isn't necessary. The controller only allows local connections by default.
Tor Browser's Tor config enforces authentication uses the cookie method, without changing any options in torrc you need to read the contents of the auth cookie to connect.
I was able to change the IP with the following code:
require 'rubygems'
$:.unshift "./tor/lib"
require 'tor'
# the cookie file contains a "password" for authentication, 32 random bytes
cookie_file = '/home/me/tor-browser_en-US/Browser/TorBrowser/Data/Tor/control_auth_cookie'
file = File.open(cookie_file, 'rb')
cookie = file.read # read contents of auth cookie to string
file.close
Tor::Controller.connect(:port => 9151, :cookie => cookie) do |tor|
p tor.signal('NEWNYM') # send NEWNYM signal (gets new IP)
end
tor.signal returns a string, which should read "250 OK" if the NEWNYM command was successful. There is some internal rate limiting which prevents this from being run too often (like every 10 seconds I think) which shouldn't be a problem for you.
EDIT: The 0.1.2 (current release) of this Gem doesn't include the signal method from the master branch. You'll need to use the latest code or replicate their code instead of calling signal.
I'm a new Ruby developer. I would like to send some concurrent requests (maximum 3 requests) at same time to get data. I know there are a lot of Http libs in Ruby that support for sending request. In the end, I choose HTTParty, however, it comes to some error when I try to send request.
response_data = Http::SearchFlightService.search(url, options)
The url value:
http://booknow.jetstar.com/Search.aspx?culture=vi-VN
And value of options params:
{:body=>{"search-origin01"=>"", "search-destination01"=>"", "ControlGroupSearchView$ButtonSubmit"=>"", "__VIEWSTATE"=>"", "undefined"=>"", "children"=>"0", "infants"=>"0", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListPassengerType_INFANT"=>"0", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListPassengerType_CHD"=>"0", "datedepart-01"=>"19/06/2016", "datereturn-01"=>"20/06/2016", "adults"=>"1", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListMarketDay1"=>"19", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListPassengerType_ADT"=>"1", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListMarketDay2"=>"20", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListMarketMonth1"=>"2016-06", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListMarketMonth2"=>"2016-06", "ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketOrigin1"=>"SGN", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListFareTypes"=>"I", "_pe_39b5379c652b_9df496572198"=>"null", "travel-indicator"=>"on", "ControlGroupSearchView$AvailabilitySearchInputSearchView$RadioButtonMarketStructure"=>"RoundTrip", "ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketDestination1"=>"HAN", "pageToken"=>"sLkmnwXwAsY=", "culture"=>"vi-VN", "locale"=>"vi-VN", "currencyPicker"=>"VND", "ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListCurrency"=>"VND"}, :headers=>{"Accept-Encoding"=>"gzip, deflate", "Content-type"=>"application/x-www-form-urlencoded"}}
My Http::SearchFlightService
class Http::SearchFlightService
include HTTParty
ssl_version :SSLv3
def self.search(url, options)
post(url, options)
end
end
It showed error
/Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/protocol.rb:153:in `read_nonblock': Connection reset by peer (Errno::ECONNRESET)
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/protocol.rb:153:in `rbuf_fill'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/protocol.rb:104:in `read'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http/response.rb:399:in `read'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http/response.rb:289:in `block in read_body_0'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http/response.rb:260:in `inflater'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http/response.rb:279:in `read_body_0'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http/response.rb:201:in `read_body'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http/response.rb:226:in `body'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http/response.rb:163:in `reading_body'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http.rb:1420:in `block in transport_request'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http.rb:1411:in `catch'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http.rb:1411:in `transport_request'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http.rb:1384:in `request'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http.rb:1377:in `block in request'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http.rb:853:in `start'
from /Users/Dona/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/net/http.rb:1375:in `request'
Please give me some advice. Thanks
httparty seems to have some bugs. Had same Errno::ECONNRESET: Connection reset by peer. Fixed by replacing httparty call to net/http
require 'net/http'
JSON.parse Net::HTTP.get(URI.parse(url))
I'm working with a Rails 3.2 application that has a mysql database and a number of models that are being indexed in Solr.
Here's what's happening:
I am running the following command:
RAILS_ENV=development bundle exec rake sunspot:reindex[1000] --trace
After indexing about 12% of the 4 million records (although it's a different percentage every time), the process inevitably bombs out with the following error and stack trace:
rake aborted!
getaddrinfo: nodename nor servname provided, or not known
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/net/http.rb:762:in `initialize'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/net/http.rb:762:in `open'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/net/http.rb:762:in `block in connect'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/net/http.rb:762:in `connect'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/net/http.rb:744:in `start'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/net/http.rb:1284:in `request'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rsolr-1.0.9/lib/rsolr/connection.rb:15:in `execute'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/solr_instrumentation.rb:14:in `block in execute_with_as_instrumentation'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/activesupport-3.2.13/lib/active_support/notifications.rb:123:in `block in instrument'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/activesupport-3.2.13/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/activesupport-3.2.13/lib/active_support/notifications.rb:123:in `instrument'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/solr_instrumentation.rb:12:in `execute_with_as_instrumentation'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rsolr-1.0.9/lib/rsolr/client.rb:167:in `execute'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rsolr-1.0.9/lib/rsolr/client.rb:161:in `send_and_receive'
(eval):2:in `post'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rsolr-1.0.9/lib/rsolr/client.rb:67:in `update'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rsolr-1.0.9/lib/rsolr/client.rb:87:in `add'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot/indexer.rb:106:in `add_documents'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot/indexer.rb:30:in `add'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot/session.rb:91:in `index'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot/session_proxy/abstract_session_proxy.rb:11:in `index'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot/session_proxy/retry_5xx_session_proxy.rb:17:in `method_missing'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot/session_proxy/abstract_session_proxy.rb:11:in `index'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot.rb:184:in `index'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/searchable.rb:261:in `block (2 levels) in solr_index'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/searchable.rb:365:in `solr_benchmark'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/searchable.rb:260:in `block in solr_index'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation/batches.rb:72:in `find_in_batches'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/querying.rb:8:in `find_in_batches'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/searchable.rb:259:in `solr_index'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/searchable.rb:203:in `solr_reindex'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/tasks.rb:64:in `block (3 levels) in <top (required)>'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot/class_set.rb:16:in `each'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot-2.0.0/lib/sunspot/class_set.rb:16:in `each'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/sunspot_rails-2.0.0/lib/sunspot/rails/tasks.rb:63:in `block (2 levels) in <top (required)>'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/task.rb:246:in `call'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/task.rb:246:in `block in execute'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/task.rb:241:in `each'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/task.rb:241:in `execute'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/task.rb:184:in `block in invoke_with_call_chain'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/task.rb:170:in `invoke'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:143:in `invoke_task'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:101:in `block (2 levels) in top_level'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:101:in `each'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:101:in `block in top_level'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:110:in `run_with_threads'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:95:in `top_level'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:73:in `block in run'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:160:in `standard_exception_handling'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/lib/rake/application.rb:70:in `run'
/Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.0.4/bin/rake:33:in `<top (required)>'
/Users/tchapin/.rbenv/versions/1.9.3-p392/bin/rake:23:in `load'
/Users/tchapin/.rbenv/versions/1.9.3-p392/bin/rake:23:in `<main>'
The app is running in development mode at localhost:3000, and solr is running at localhost:8982. Here's my solr.rake file:
Rake::Task['sunspot:reindex'].enhance ['sunspot:scope_models_for_index']
Rake::Task['sunspot:solr:reindex'].enhance ['sunspot:scope_models_for_index']
namespace 'sunspot' do
task :scope_models_for_index => :environment do
require 'rsolr/error'
Dir.glob(Rails.root.join('app/models/**/*.rb')).each { |path| require path }
# Add the GC
commit_extension = Module.new do
def commit
GC.start
super
end
end
Sunspot.extend commit_extension
# Set all the models default scopes the index scope
Sunspot.searchable.each do |model|
model.class_eval do
default_scope ->{ sunspot_index } if model.respond_to?(:sunspot_index)
end
end
end
end
Anyone know what might be causing this error, or how to fix it?
Apparently the problem is due to an exception: SocketError.
The exception occurs in the file /Users/tchapin/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rsolr-1.0.9/lib/rsolr/connection.rb:
def execute client, request_context
h = http request_context[:uri], request_context[:proxy], request_context[:read_timeout], request_context[:open_timeout]
request = setup_raw_request request_context
request.body = request_context[:data] if request_context[:method] == :post and request_context[:data]
begin
response = h.request request
charset = response.type_params["charset"]
{:status => response.code.to_i, :headers => response.to_hash, :body => force_charset(response.body, charset)}
rescue Errno::ECONNREFUSED => e
raise(Errno::ECONNREFUSED.new(request_context.inspect))
# catch the undefined closed? exception -- this is a confirmed ruby bug
rescue NoMethodError
$!.message == "undefined method `closed?' for nil:NilClass" ?
raise(Errno::ECONNREFUSED.new) :
raise($!)
end
end
It's not the prettiest fix, and it's obviously not a solution for production code, but I was able to temporarily solve the problem by adding a rescue handler for the SocketError exception, like so:
def execute client, request_context
h = http request_context[:uri], request_context[:proxy], request_context[:read_timeout], request_context[:open_timeout]
request = setup_raw_request request_context
request.body = request_context[:data] if request_context[:method] == :post and request_context[:data]
retries = 10
begin
response = h.request request
charset = response.type_params["charset"]
{:status => response.code.to_i, :headers => response.to_hash, :body => force_charset(response.body, charset)}
rescue Errno::ECONNREFUSED => e
raise(Errno::ECONNREFUSED.new(request_context.inspect))
# catch the undefined closed? exception -- this is a confirmed ruby bug
rescue NoMethodError
$!.message == "undefined method `closed?' for nil:NilClass" ?
raise(Errno::ECONNREFUSED.new) :
raise($!)
rescue SocketError => e
puts e
if retries > 0
puts "SocketError! Retrying connection after 1 second..."
retries -= 1
sleep(1)
retry
else
puts "SocketError: Not responding after 10 retries! Giving up!")
exit
end
end
end
Additionally, it looks like my local copy of Solr was having some issues with running out of memory. I solved the memory problem by updating my sunspot.yml file accordingly:
development:
solr:
hostname: 127.0.0.1
port: 8982
min_memory: 512M
max_memory: 2G
log_level: INFO
# open_timeout: 3
# read_timeout: 3
Updated to include Redis/Resque versions and stack trace (below):
redis (3.0.4)
redis-namespace (1.3.0)
redis (~> 3.0.0)
redis-store (1.1.2)
redis (>= 2.2.0)
resque (1.24.1)
mono_logger (~> 1.0)
multi_json (~> 1.0)
redis-namespace (~> 1.2)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
resque-scheduler (2.0.1)
redis (>= 2.0.1)
resque (>= 1.20.0)
rufus-scheduler
I'm seeing intermittent Redis::TimeoutError: Connection timed out on heroku while writing a moderately sized array (~200 Fixnums) to the Redis store using the Rails.cache.fetch command.
I'm also using Resque.
I see here that the Redis::Client can receive a timeout option, but I don't see where to pass initialization options to Redis.
I'm using the standard heroku resque.rb:
rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
rails_env = ENV['RAILS_ENV'] || 'development'
resque_config = YAML.load_file(rails_root + '/config/resque.yml')
ENV['REDIS_URI'] = resque_config[rails_env]
Resque.redis = resque_config[rails_env]
Resque.inline = rails_env == 'test'
require 'resque_scheduler'
require 'resque/scheduler'
require 'resque_scheduler/server'
Resque.schedule = YAML.load_file(rails_root + '/config/resque-schedule.yml')
Resque.before_fork do
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
Resque.after_fork do
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
I assume that a Redis client is instantiated here. Is this a different client from the one instantiated in production.rb:
rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
rails_env = ENV['RAILS_ENV'] || 'development'
resque_config = YAML.load_file(rails_root + '/config/resque.yml')
config.cache_store = :redis_store, resque_config[rails_env], { expires_in: 14.days }
The options hash there is for Rails.cache options as far as I know. Is a new client instantiated here? How can I pass options to this one?
Updated to include this experiment in the heroku console implying that they are different client instances:
irb(main):002:0> Rails.cache
=> #<ActiveSupport::Cache::RedisStore:0x00000003860e18 #data=#<Redis client v3.0.4 for redis://spinyfin.redistogo.com:9485/0>, #options={:expires_in=>14 days}>
irb(main):003:0> Resque.redis.redis
=> #<Redis client v3.0.4 for redis://spinyfin.redistogo.com:9485/0>
irb(main):004:0> Rails.cache.instance_variable_get(:#data).object_id == Resque.redis.redis.object_id
=> false
Stack trace:
Redis::TimeoutError: Connection timed out
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:208:in `rescue in io'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:206:in `io'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:214:in `read'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:84:in `block in call'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:187:in `block (2 levels) in process'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:295:in `ensure_connected'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:177:in `block in process'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:256:in `logging'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:176:in `process'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:84:in `call'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:644:in `block in setex'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:36:in `block in synchronize'
from /app/vendor/ruby-1.9.3/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:36:in `synchronize'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:643:in `setex'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-store-1.1.2/lib/redis/store/interface.rb:17:in `setex'
... 11 levels...
from /app/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active_support/cache.rb:299:in `fetch'
...SNIP...
...my code...
...SNIP...
from /app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation/delegation.rb:6:in `each'
from /app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation/delegation.rb:6:in `each'
...SNIP...
...my code...
...SNIP...
from (irb):5
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'irb(main):006:0> ! Heroku client internal error.
! Search for help at: https://help.heroku.com
! Or report a bug at: https://github.com/heroku/heroku/issues/new
Error: Operation timed out (Errno::ETIMEDOUT)
Backtrace: /usr/local/heroku/ruby/lib/ruby/1.9.1/openssl/buffering.rb:121:in `sysread'
/usr/local/heroku/ruby/lib/ruby/1.9.1/openssl/buffering.rb:121:in `readpartial'
/Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:69:in `block in start'
/Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:53:in `loop'
/Users/me/.heroku/client/lib/heroku/client/rendezvous.rb:53:in `start'
/Users/me/.heroku/client/lib/heroku/command/run.rb:132:in `rendezvous_session'
/Users/me/.heroku/client/lib/heroku/command/run.rb:119:in `run_attached'
/Users/me/.heroku/client/lib/heroku/command/run.rb:24:in `index'
/Users/me/.heroku/client/lib/heroku/command.rb:206:in `run'
/Users/me/.heroku/client/lib/heroku/cli.rb:28:in `start'
/usr/local/heroku/bin/heroku:24:in `<main>'
Command: heroku run rails c
Plugins: heroku-redis-cli
Version: heroku-toolbelt/2.39.4 (x86_64-darwin10.8.0) ruby/1.9.3
The "Connection timed out" message means that redis-rb is having trouble initiating a connection to your Redis server. Normally, you'd want to just initialize your Redis connection once on app boot. However, because Resque forks (rather than using threads like Sidekiq), it has to initialize a fresh Redis connection for every individual job.
Normally, that's not a problem, but Heroku has intermittent issues with creating new Redis connections. I've seen this issue across languages / client libraries / Redis hosts, and beyond reducing the number of Redis connections you create, the only way to mitigate the issue is to automatically retry connecting to Redis a few times in your Resque.after_fork block. (Eg. catch the timeout error and either retry or re-raise the exception if you've tried 3 times)
This isn't much of an answer, but at the recommendation of a colleague, I switched from RedisToGo to openredis and these problems went away immediately.
You can't pass both a URL and an options hash to config.cache_store, because of this bug:
config.cache_store = :redis_store, resque_config[rails_env], { expires_in: 14.days }
If you pass a URL and an options hash, it ignores the URL and defaults to localhost, which is probably why you're seeing a timeout (I just had the same issue).
Instead, do something like this:
redis_uri = URI.parse(ENV["REDISTOGO_URL"])
config.cache_store = :redis_store, {
host: redis_uri.host,
port: redis_uri.port,
password: redis_uri.password,
namespace: "cache",
expires_in: 7.days
}