Rails Rake task displayed execution expired message and program stopped - ruby-on-rails

I have a rake task to load car's image from the table websites using paperclip. The image stored in database as a remote link.
Here is my code and i'm using ruby 1.8.7, rails 2.3.8 and DB mysql.
namespace :db do
task :load_photo => :environment do
require 'rubygems'
require 'open-uri'
require 'net/http'
require 'paperclip'
begin
images =Website.find(:all,:conditions=>["image_url is not null"])
images.each do |photo|
url = URI.parse(photo.image_url)
Net::HTTP.start(url.host, url.port) do |http|
if http.head(url.request_uri).code == "200"
Car.update_attribute(:photo,open(url))
end
end
end
rescue Exception => e
end
end
end
Run above rake task by db:load_photo. In my table (Website) has 60,000 rows. Rake task running upto 10000 rows only and execution terminated with an error message "execution expired".
Can any one help me to figure this out?
Thanks in advance.

You may find it more performant to run it in batches, active record has a find_in_batches method which stops loading all the records into memory at one time.
http://ryandaigle.com/articles/2009/2/23/what-s-new-in-edge-rails-batched-find
You could change your code to look like:
namespace :db do
task :load_photo => :environment do
require 'rubygems'
require 'open-uri'
require 'net/http'
require 'paperclip'
Website.find_in_batches(:conditions=>["image_url is not null"]) do |websites|
websites.each do |website|
begin
url = URI.parse(website.image_url)
Net::HTTP.start(url.host, url.port) do |http|
if http.head(url.request_uri).code == "200"
Car.update_attribute(:photo,open(url))
end
end
rescue Exception => e
end
end
end
end
end

I can only guess, but it looks like you're making a little DoS attack to the server you're pulling images from.
You can try to play with a little delay between sequential requests (like "sleep 1").
Also, if your "execution expired" is a Timeout::Error exception, then you can't catch it with
rescue Exception => e
because Timeout::Error is not a subclass of StandardError, it is a subclass of the Interrupt class. You have to catch it explicitly, like so:
rescue Timeout::Error => e

Related

Could Not Load Model Data in rake task only in production

I have a rake task
namespace :authentication do
desc "Automatically runs authentication tester"
task :tester => :environment do
begin
Auth.perform
rescue
SystemEvent.error(50049, "Authentication Tester Finished Unsuccessfully.")
end
end
end
in my Auth.perform, I have used,
Customer.first.symbol
I am loading Customer from database. But it always comes to the rescue block saying
undefined method 'symbol' for nil:class
In my application.rb
config.autoload_paths += Dir.glob("#{Rails.root}/lib/**/*").select{|d| File.directory?(d)}
config.autoload_paths += Dir.glob("#{Rails.root}/app/models/**/*").select{|d| File.directory?(d)}
config.autoload_paths += ["#{Rails.root}/services/"]
This calls Auth.perform in development. Only in production it comes to rescue block. Is this something because I am missing?
require 'rake'
Please provide a solution. It has been one week I am picking my head.
Please Note: this rake task is called by a cron running in another instance.

Schedule a one-time Resque job on heroku on application start in Rails

I am using Resque and Resque Schedule to start a job that has to be run immediately on the application start. Other scheduled jobs are loaded every 30 seconds.
This is the code for my config/initializers/redis.rb
require 'rake'
require 'resque'
require 'resque/server'
require 'resque_scheduler/tasks'
# This will make the tabs show up.
require 'resque_scheduler'
require 'resque_scheduler/server'
uri = URI.parse(ENV["REDISTOGO_URL"])
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
Resque.redis = REDIS
Dir["#{Rails.root}/app/workers/*.rb"].each { |file| require file }
Resque.enqueue(AllMessageRetriever)
Resque.schedule = YAML.load_file(Rails.root.join('config', 'schedule.yml'))
When the application is started up, the AllMessageRetriever gets run 2-3 times rather than only once. Do the initializers get called more than once? This happens both on Heroku and my local environment?
Is it possible to set a delayed job in Resque-Scheduler which will only get executed once and immediately on runtime?
The code for AllMessageRetriever. Basically it loops over a table and calls an external API to get data and then updates it to the table. This entire task happens 2-3 times if I add the enqueue method in initializer file
require 'socialcast'
module AllMessageRetriever
#queue = :message_queue
def self.perform()
Watchedgroup.all.each do |group|
puts "Running group #{group.name}"
continueLoading=true
page=1
per_page=500
while(continueLoading == true)
User.first.refresh_token_if_expired
token = User.first.token
puts "ContinueLoading: #{continueLoading}"
#test = Socialcast.get_all_messages(group.name,token,page,per_page)
messagesArray = ActiveSupport::JSON.decode(#test)["messages"]
puts "Message Count: #{messagesArray.count}"
if messagesArray.count == 0
puts 'count is zero now'
continueLoading = false
else
messagesArray.each do |message|
if not Message.exists?(message["id"])
Message.create_with_socialcast(message, group.id)
else
Message.update_with_socialcast(message)
end
end
end
page += 1
end
Resqueaudit.create({:watchedgroup_id => group.id,:timecompleted => DateTime.now})
end
# Do anything here, like access models, etc
puts "Doing my job"
end
end
Rake
Firstly, why are you trying to queue on init?
You'd be much better delegating to a rake task which is called from an initializer.
This will remove dependency on the initialize process, which should clear things up a lot. I wouldn't put this in an initializer itself, as it will be better handled elsewhere (modularity)
Problem
I think this line is causing the issue:
Resque.enqueue(AllMessageRetriever)
Without seeing the contents of AllMessageRetriever, I'd surmise that you're AllMessageRetriever (module / class?) will be returning the results 2/3 times, causing Resque to add the (2 / 3 times) data-set to the queue
Could be wrong, but it would make sense, and mean your issue is not with Resque / Initializers, but your AllMessageRetriever class
Would be a big help if you showed it!

Resque error- wrong number of arguments(0 for 1)

I am using rescue to handle all the heavy lifting background tasks,
In my library/parsers/file.rb I have
Resque.enqueue(Hello)
This will redirect app/workers/file.rb where I have
class Hello
def self.perform(page)
.......
.......
end
rescue Exception => e
log "error: #{e}"
end
end
my lib/tasks/resque.rake file is
require "resque/tasks"
task "resque:setup" => :environment
I am able to queue the jobs buts when i try to execute the job using
rake resque:work QUEUE=*
it is throwing an error by saying
argument error
wrong number of arguments (0 for 1)
what am I doing wrong in this?
pjumble is exactly right, you're not passing the page.
Resque.enqueue(Hello, page_id)
enqueue takes the Job followed by the args which go into the perform action. If you had:
class Hello
def self.perform(page_number, page_foo, page_bar)
...
end
end
Then you would do this:
Resque.enqueue(Hello, page_number, page_foo, page_bar)

Ruby on Rails Developer

Andrew
I am new for ROR Developer. i have one table to insert car images. but, that images are remote url. I have to insert 60,000 rows. i got like this "error execution terminated". Can you help how do i fix this issue?
Here My Code:
namespace :db do
task :load_photo => :environment do
require 'rubygems'
require 'open-uri'
require 'net/http'
require 'paperclip'
Website.find_in_batches(:conditions=>["image_url is not null"]) do |websites|
websites.each do |website|
begin
url = URI.parse(website.image_url)
Net::HTTP.start(url.host, url.port) do |http|
if http.head(url.request_uri).code == "200"
Car.update_attribute(:photo,open(url))
end
end
rescue Exception => e
end
end
end
end
end
I would suggest you to not rescue all Exception like you did with :
rescue Exception => e
end
then you will have (and be able to give us) more information about the error generated.
Notice that it is a good practice to rescue only exception you want.

Request a page with cron to update cache

I use http caching on Heroku:
def homepage
response.headers['Cache-Control'] = 'public, max-age=86340'
...
end
I also have added Heroku's free cron addon:
desc "This task is called by the Heroku cron add-on"
task :cron => :environment do
if Time.now.hour == 0 # run at midnight
# I want to request a page here
end
end
Could you tell me what should I put inside this file in order to request a page?
A similar question has been asked at How to force fragment cache on rails from cron schedule?
They don't provide an example in the answer.
require 'uri'
require 'net/http'
desc "This task is called by the Heroku cron add-on"
task :cron => :environment do
if Time.now.hour == 0 # run at midnight
uri = URI.parse('http://my-app.heroku.com/page')
Net::HTTP.get(uri)
end
end
That should do it.

Resources