Steps to run cron on a Ruby on Rails 2.3 project - ruby-on-rails

Can anyone suggest to me a manual or a website with resources for running cron on my Ruby on Rails project? These are the relevant code snippets:
schedule.rb
every 1.day, :at => '10:40 am' do
runner "Person.update_person_state"
end
person_controller.rb
def update_person_state
Person.update_person_state
end
file person.rb
def self.update_person_state
#list_persons = Person.find(:all, :conditions => { :state => 0, :date_expired => Date.today.strftime("%Y-%m-%d")})
print #list_persons.inspect
print Date.today.strftime("%Y-%m-%d")
#list_persons.each do |person|
person.state = 2
person.save
end
end

Related

How to speed up sitemap_generator with parallel gem

I am trying to speed up sitemap_generator by adding parallelization via the parallel gem. I have the following code but my groups aren't getting written to the public/sitemaps directory. I am thinking it's due to lambdas getting executed in a different space in parallel. Any feedback would be helpful. Thanks!
#!/usr/bin/env ruby
require 'rubygems'
require 'sitemap_generator'
require 'benchmark'
require 'parallel'
require 'random-word'
SitemapGenerator::Sitemap.default_host = "http://localhost"
a = lambda {
SitemapGenerator::Sitemap.group(:filename => :biz, :sitemaps_path => 'sitemaps/biz/') do
(1..1000).each do |index|
url = "/#{RandomWord.adjs.next}/#{RandomWord.nouns.next}"
add url, :priority => 0.8
end
end
}
b = lambda {
SitemapGenerator::Sitemap.group(:filename => :wedding_ugc, :sitemaps_path => 'sitemaps/ugc') do
(1..1000).each do |index|
url = "/#{RandomWord.adjs.next}/#{RandomWord.nouns.next}"
add url, :priority => 0.8
end
end
}
#working example
# SitemapGenerator::Sitemap.default_host = "http://localhost"
# SitemapGenerator::Sitemap.create(:compress => false) do
# group(:filename => :biz, :sitemaps_path => 'sitemaps/biz/') do
# (1..1000).each do |index|
# url = "/#{RandomWord.adjs.next}/#{RandomWord.nouns.next}"
# add url, :priority => 0.8
# end
# end
# end
puts Time.now
Parallel.each([a,b]){|job| job.call()}
puts Time.now
I got this working and posted the solution on github here
Here is the code incase the url gets broken.
SitemapGenerator::Sitemap.create(:compress => false, :create_index => false) do
group1 = lambda {
group = sitemap.group(:filename => :group1, :sitemaps_path => 'sitemaps/group1') do
Record.find_each do |record|
add '/record/path'
end
end
group.sitemap.write unless group.sitemap.written? #write if not full
}
# group2 like above...
Parallel.each([group1, group2], :in_processes => 8) do |group|
group.call
end
end
#regenerate the index sitemap xml file because I couldn't figure out how to track it with multiple processes
SitemapGenerator::Sitemap.create(:compress => false) do
Dir.chdir(sitemap.public_path.to_s)
xml_files = File.join("**", "sitemaps", "**", "*.xml")
xml_file_paths = Dir.glob(xml_files)
xml_file_paths.each do |file|
add file
end
end

Wice_Grid CSV export not working - Uninitialized constant CSV::Writer

I "inherited" a rails aplication running with ruby 1.8.7 in development.
I have a wice_grid table which I'm trying to export in CSV and in development all goes perfect.
When I push it to production, i get the following error:
uninitialized constant CSV::Writer
The production machine is running Ruby 1.9.1 and from what I read, I suppose the problem comes from there.
I've tried to put:
required 'csv'
In the controller or the model, but nothing happens, development works, production does not.
Here is the controller code:
def index
require 'csv'
#service_requests = initialize_grid(ServiceRequest,
:name => "solicitudes",
:order => "created_at" ,
:order_direction => 'desc',
:include => [:user, :service],
:enable_export_to_csv => true,
:csv_file_name => 'Listado de Solicitudes'
)
export_grid_if_requested('solicitudes' => 'service_requests') do
#Si se pulsa en exportar se exportan todos las celdas de la tabla seleccionada (con filtros aplicados)
end
end
Here is the part of the view, which calls a partial:
<%= render :partial => 'service_requests' %>
Here is the partial, cropped for making the question not too long:
<%= grid(#service_requests, :show_filters => :always) do |service_request|
[...]
service_request.column :column_name => 'Nombre' , :attribute_name => 'name', :model_class => User do |sr|
sr.user.name
end
service_request.column :column_name => 'Apellidos' , :attribute_name => 'lastName' , :model_class => User do |sr|
sr.user.lastName
end
[...]
end %>
I read this thread but didnt help me much: write csv in ruby 1.9 and CSV::Writer
Thank you all in advance!
Somewhere, that you haven't posted, you are referencing CSV::Writer. This works locally because you're using Ruby 1.8.7, but your production server is using Ruby 1.9.1. CSV::Writer was deprecated with Ruby 1.9.
From the the docs:
# * The old CSV's Reader and Writer classes have been dropped.
Step one is to upgrade your local Ruby to the same version as the server. This will give you the same error locally, which should go away once you find and remove that CSV::Writer.
The CSV docs give examples of how to use the current CSV class to accomplish what CSV::Writer used to do. Here's an example:
# == Writing
#
# === To a File
#
# CSV.open("path/to/file.csv", "wb") do |csv|
# csv << ["row", "of", "CSV", "data"]
# csv << ["another", "row"]
# # ...
# end
Upgrading Ruby will probably raise other errors. But Ruby 1.8.7 was retired in 2013 so these are problems you're going to want to fix now rather than later.
Good luck!

How do you output call tree profiling for KCacheGrind with ruby-prof for a Rails app?

According to the documentation, you can profile Rails apps
http://ruby-prof.rubyforge.org/
I added this to my config.ru
if Rails.env.development?
use Rack::RubyProf, :path => 'tmp/profile'
end
However it only outputs the following files
users-1-call_stack.html
users-1-flat.txt
users-1-graph.html
users-1-graph.txt
The output is completely incomprehensible. So I downloaded QCacheGrind for Windows.
http://sourceforge.net/projects/qcachegrindwin/?source=recommended
It won't read any of those files. The ruby-prof docs says that you can generate KCacheGrind files
RubyProf::CallTreePrinter - Creates a call tree report compatible with KCachegrind.
But it won't say how to do it with Rails. I looked at the page for RubyProf, but it was empty.
http://ruby-prof.rubyforge.org/classes/Rack/RubyProf.html
Ruby 2.0.0, Rails 4.0.3
helper_method :profile
around_action :profile, only: [:show]
def profile(prefix = "profile")
result = RubyProf.profile { yield }
# dir = File.join(Rails.root, "tmp", "profile", params[:controller].parameterize)
dir = File.join(Rails.root, "tmp", "profile")
FileUtils.mkdir_p(dir)
file = File.join(dir, "callgrind.%s.%s.%s" % [prefix.parameterize, params[:action].parameterize, Time.now.to_s.parameterize] )
open(file, "w") {|f| RubyProf::CallTreePrinter.new(result).print(f, :min_percent => 1) }
end
Change config.ru
use Rack::RubyProf, :path => ::File.expand_path('tmp/profile'),
:printers => {::RubyProf::FlatPrinter => 'flat.txt',
::RubyProf::GraphPrinter => 'graph.txt',
::RubyProf::GraphHtmlPrinter => 'graph.html',
::RubyProf::CallStackPrinter => 'call_stack.html',
::RubyProf::CallTreePrinter => 'call_grind.txt',
}

Sidekiq worker not able to write to database or log file

I'm building an app on Herokou and Redis that sends an SMS messages for every row in an input CSV file which contains the mobile phone number. The message is sent using Twilio in a sidekiq worker shown below. The problem is that even though the SMS is being sent for all the rows in the CSV, the database write (TextMessage.create) and log write (puts statement) only executes for one row in the CSV. There is one Sidekiq worker spawned for each row in the CSV file. It seems like only one Sidekiq worker has I/O (DB, file) access and it locks it from the other Sidekiq workers. Any help would be appreciated.
sidekiq worker:
require 'sidekiq'
require 'twilio-rb'
class TextMessage < ActiveRecord::Base
include Sidekiq::Extensions
def self.send_message(number, body, row_index, column_index, table_id)
puts "TextMessage#send_message: ROW INDEX: #{row_index} COLUMN INDEX: #{column_index} TABLEID: #{table_id} BODY: #{body} PHONE: #{number}"
Twilio::Config.setup :account_sid => 'obfuscated', :auth_token => '<obfuscated>'
sms = Twilio::SMS.create :to => number, :from => '+17085555555', :body => body + ' | Sent: ' + Time.now.in_time_zone('Central Time (US & Canada)').strftime("%m/%d/%Y %I:%M%p Central")
TextMessage.create :to => number, :from => '+17085555555'
ImportCell.add_new_column(table_id, row_index, column_index, "Time Sent", Time.now.in_time_zone('Central Time (US & Canada)').strftime("%m/%d/%Y %I:%M%p Central"))
end
end
call to sidekiq worker:
TextMessage.delay_until(time_to_send, :retry => 3).send_message(phone, 'Scheduled: ' + time_to_send.in_time_zone('Central Time (US & Canada)').strftime("%m/%d/%Y %I:%M%p Central"), row_index, column_index, table.id)
column_index += 1
Heroku Procfile
worker: bundle exec sidekiq -C config/sidekiq.yml
sidekiq.yml
:verbose: false
:concurrency: 3
:queues:
- [default, 5]
config/initializers/redis.rb:
uri = URI.parse(ENV["REDISTOGO_URL"])
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
Sidekiq.configure_server do |config|
database_url = ENV['DATABASE_URL']
if(database_url)
ENV['DATABASE_URL'] = "#{database_url}?pool=25"
ActiveRecord::Base.establish_connection
end
end
I am one of the people who commented on your question, just fixed it!
You are using .create which SideKiq seemed to not like, so I tried using .new and then .save which made it work! I think it has to do with .create not being thread safe or something of the sort, but I honestly have no idea.
Non Working code:
class HardWorker
include Sidekiq::Worker
def perform(name, count)
puts 'Doing some hard work!'
UserInfo.create(
:user => "someone",
:misc1 => 0,
:misc2 => 0,
:misc3 => 0,
:comment => "Made from HardWorker",
:time_changed => Time.now
)
puts 'Done with hard work!'
end
end
Working code:
class HardWorker
include Sidekiq::Worker
def perform(name, count)
puts 'Doing some hard work!'
a_row = UserInfo.new(
:user => "someone",
:misc1 => 0,
:misc2 => 0,
:misc3 => 0,
:comment => "Made from HardWorker",
:time_changed => Time.now
)
a_row.save
puts 'Done with hard work!'
end
end

Feedzirra in Rails 3

I am trying to get feedzirra running on rails 3, I tried by some methods I have found on the internet.
This is in my gemfile:
source 'http://gems.github.com'
gem 'loofah', '1.0.0.beta.1'
group :after_initialize do
gem 'pauldix-feedzirra'
end
And i've out this after bundle.setup in root.rb
Bundler.require :after_initialize
And this is the code in my model (movie.rb)
class Movie < ActiveRecord::Base
def self.import_from_feed
feed = Feedzirra::Feed.fetch_and_parse("url-to.xml")
add_entries(feed.entries)
end
private
def self.add_entries(entries)
entries.each do |entry|
unless exists? :guid => entry.id
create!(
:title => entry.title,
:synopsis => entry.synopsis,
:cover => entry.cover,
:duration => entry.duration,
:channel => entry.channel,
:imdb_rating => entry.imdb_rating,
:imdb_votes => entry.imdb_votes,
:imdb_id => entry.imdb_votes
)
end
end
end
end
I try to run the import_from_feed function from the console and I keep getting this error:
>> Movie.import_from_feed
NameError: uninitialized constant Movie::Feedzirra
from /Users/myname/Ruby/appname/app/models/movie.rb:3:in `import_from_feed'
from (irb):1
Can someone help me out? Been trying for ages now!
Two things:
Just add the gem, not under :after_initialize
Use the feedzirra gem, not the old pauldix-feedzirra one.

Resources