Rider Jones
July 8th, 2006
Check out Rider Jones out of Vancouver.
There’s a lot of garbage on MySpace to wade through some times but once in a while you come across some great music. I think their MySpace page is burned into my screen at this point. Can’t wait until I get the EP’s.
WhatMyFriendsLike.com
July 6th, 2006
In addition to MySpace Maps I also created WhatMyFriendsLike.com
It lets you create a ranked list of all the music, movies and books your MySpace friends like.
This one was also written entirely in Ruby on Rails sharing most of the code with MySpace Maps.
Multiple RailsCron Instances
July 6th, 2006
Just to follow up on my last post about using RailsCron.
If you want to run multiple instances of RailsCron you need to change the startup tasks in the rake file.
In my particular case I wanted a separate instance running for each of the sites that required it. I’m running them all as Daemons so I changed the cron_start target in my rake file.
From the root of of your app edit the rake file:vi vendor/plugins/trunk/tasks/startup.rake
Change
desc "Starts RailsCron as a daemon"
task :cron_start do
if `#{sudo "ps x | grep RailsCron | grep -v grep"}`.strip.blank?
mode = ENV['RAILS_ENV'] || "development"
puts `#{sudo "nohup ruby script/runner -e #{mode} \"RailsCron.start\" > /dev/null 2>&1 &"}`
else
puts "RailsCron already started"
end
end
To the following:
desc "Starts RailsCron as a daemon"
task :cron_start do
mode = ENV['RAILS_ENV'] || "development"
puts `#{sudo "nohup ruby script/runner -e #{mode} \"RailsCron.start\" > /dev/null 2>&1 &"}`
end
This removes the check for an existing RailsCron process and lets you start a new one. Be careful.
Now you can run rake cron_start from the root of each app that requires a RailsCron instance. Running rake cron_stop will stop all the RailsCron processes so you’ll have to start each one up again.
MySpace Maps
July 5th, 2006
I just finished up this little site that maps all your MySpace friends using Google Maps. For those interested the app is written entirely in Ruby on Rails. The maps are rendered using Google Maps and the Geocoding is done through Yahoo.
I’ll probably be adding support for Yahoo Maps when I have some time.
If you have suggestions, problems, or would just like to discuss the application feel free to comment here.
Installing and Using RailsCron
July 4th, 2006
I recently started using Kyle Maxwell’s RailsCron for a couple Ruby on Rails apps I’ve been playing with. Cron turned out to be a headache in my case and I wanted ActiveRecord support without having to jump through any hoops.
Some of the shortcomings of Cron with RoR (from the RailsCron readme):- Significant startup resources required
- Lots of RAM to run simultaneous processes
- Hard to start/stop/affect the background processes from within Rails.
The documentation is sparse and there are very few examples to be found online.
This is straight from the readme:RailsCron.create(
:command => "Object.do_something()",
:start => 2.minutes.from_now,
:every => 12.hours, # default: 1.day
:finish => 2.years.from_now # optional
)
RailsCron.destroy_all
RailsCron.find_by_command "some_command"
There are a couple ways to install. Here’s what I did. From the root of your rails app run:
./script/plugin install http://svn.kylemaxwell.com/rails_cron/trunk
I set it up to run in the background. In my model I put the following:
class User < ActiveRecord::Base
background :update_accounts, :every => 1.minute, :concurrent => false
def self.update_accounts
# do some scheduled processing
end
end
The above will run the update_accounts method every minute. You can set it up so that it can run separate threads concurrently if it’s still working on the old one. It didn’t make sense in my case so I used :concurrent => false.
It has the following set of rake tasks:- cron_start—Starts RailsCron as a daemon
- cron_foreground—Starts RailsCron in the foreground
- cron_stop—Graceful stop
- cron_kill
- cron_graceful—Graceful restart
- cron_status
For example to stop then restart RailsCron you can run the following:
rake cron_graceful
That’s it. It should create a table in your database to keep track of the tasks.
HTTP get Timeout
July 3rd, 2006
One of my apps does quite a few http requests (using Net::HTTP.get) for pages from another site.
I kept running into timeout problems that I initially assumed were http timeouts since it took up to 5 minutes to run sometimes. After banging my head against it for a while I finally came up with a solution for handling slow responding or non-responsive websites. Basically it catches the timeout error and reattempts the request. In my case I don’t care about the exception raised except to make a new request, but you might want to keep track of it and raise it at the end to do something with it.
# retrieve a page
def self.get_page(url)
retrycount = 0
resp = nil
begin
timeout(60) do
resp = Net::HTTP.get(URI.parse(url))
resp.to_s
end
rescue TimeoutError
if(retrycount < 5)
retrycount+=1
retry
else
logger.info("ERROR url: " + url)
logger.info("ERROR Timeout error in get_page, attempt #" + retrycount.to_s)
nil
end
end
resp.to_s
rescue Exception => exception
logger.info("ERROR Unknown error in get_page")
logger.info(exception.class.to_s + " " + exception.message.to_s + " " + exception.backtrace.to_s)
nil
end
This example will retry 5 times before giving up but you can change yours to attempt retries for specific cases.

