Update: If you’re going to need a scheduler, forget ‘Whenever’ and go with Rufus. Details below in Red…
It’s been awhile since I’ve ventured into Rails.
I’ve been doing most of my development in Grails these days. Groovy/Grails has one downside – web automation. Groovy’s main framework for that (GEB) is a joke of a web automation framework. My tried and true web automation framework is still Watir running in Ruby.
So I thought, “Hey, why not build out a sample tool in Rails and I can leverage the Ruby/Watir framework…” So I went back into Rails and started the process of development of a sample tool. I’ve hit one roadblock after another, to the point that I’m seeing Rails to seriously lack when compared to Grails.
One such problem is using cron in Rails. Say you have a controller that has a method you want called every X Min, each hour. In Grails, I installed the Quartz plugin and it was super simple. You basically call the controller.method() in the quartz Job and it runs on the schedule you set.
In Rails… well let me tell you my sad tale.
Rails Installation Fun
First, I installed Rails… I expected to do this by installer, but the push in the documentation is to use RVM to install the latest ruby, and then do a gem install rails. “Ok. I’ll do that,” I think to myself.
So I have multiple Ruby versions installed… I have JRuby 1.7**** which depends on Ruby 1.9.3 (Ugh!!!) which I had to downgrade OSX to set up… but I need that combo for working with Sikuli. Anyway…. now I have a new Ruby 2.1.1 installed. I create my Rails 4.* project and get to work.
Rails Whenever GEM
Rails has a gem called ‘Whenever.’ The Whenever gem is sorta like the Quartz plugin in grails. It sets up a schedule of tasks to be run. Sounds great. But it doesn’t run. No error, nothing.
I rechecked the simple documentation on the Whenever gem:
I mean it’s short and sweet, and I’m not seeing a problem with what I have….
It’s so lame. I mean, not even a error message. Literally the server starts, but nothing outputs. I have the job set to 1.second to echo ‘Test’ and nothing! That’s as simple as a job can get, and it isn’t working. Without an error message, I’m forced to google: “Rails Whenever not working.”
I see these questions and answers:
Basically it sounds like if there are multiple versions of Ruby (i.e. RVM managed Ruby installs) then it could be causing this issue, as Whenever might be kicking off in an unsupported version of Ruby.
That is very logical, and equally very frustrating. Why would people push RVM, if issues like this in GEMS are potentially possible? Why would the GEM have no way to mitigate this, or warn the users about this?
What’s the solution?
Well that stack overflow says I should use a .rvmrc file in the root of my project… it neglects what the content of that file should be…. so I googled “rvmrc” and I saw some examples on it:
Ok, I do that… Rerun the server… nothing. No errors, nothing!
Ok… I google some more (hours have gone by at this point…) when I come across this post:
This guy says we have to do a “whenever -i” to add it to the cron tab. uh, what? The simple gem doc didn’t mention that… but ok… and sure enough, I FINALLY got my first error. I got this output:
`parse_time’: Time must be in minutes or higher (ArgumentError)
Wait… What? You mean, I can’t schedule a job for under 10min? WHAT??? Also, sure, got that, why isn’t the job running on server start? My expectation would be: Server starts, job kicks off… job repeats X min.
This isn’t a limitation of Cron, as Cron can be run in min under 10, even at the level of seconds: http://www.thegeekstuff.com/2011/07/cron-every-5-minutes/
Not only that, but this cron gem really uses cron, so it won’t work on a PC… Unlike the Groovy/Grails quartz plugin which runs on any machine regardless of OS.
Update: So after waiting the 11min I set in my cron (and whenever -i accepted) it still didn’t work. I let it run it’s 11+min… never saw the action (echo ‘Test’) work. What a waste of time. I’m done with it.
At this point, having dealt with most of my day being wasted in this venture, I’m beat. This wasn’t all I went through with Rails. Hardly. This was just the icing on the cake. Prior to this I had to fight with RVM, Rails installs, had to reinstall Ruby 2.1.1, and it got corrupted, had to uninstall it completely (RVM uninstall) and then install it fresh… dealt with issues generating a controller (for crying out loud, how is it hard to generate a controller???)
Controller Generation Problems
Here I was generating a controller with: rails g controller NAME
It would just hang.
I had to kill it and try and figure out what the issues was. You know what it was??? OMG this is great. The issue was this:
Seriously, that’s BETA software guys. Come on, generating anything is the second action you take (after rails new [project name]), how did that get overlooked? So the simple workaround for that was to kill all spring sessions in memory… i.e. ps -ef | grep spring then… Kill -9 [pid]
Update: After looking around in Ruby/Rails a bit more, I found another scheduler that actually works. It lets me schedule items under 10min and it works. It’s also super easy to set up. It’s called the Rufus Scheduler and is installed via: gem install rufus-scheduler for more info, check out: http://www.intridea.com/blog/2009/2/13/dead-simple-task-scheduling-in-rails
Well… I’m done with Rails for awhile. I just can’t waste time like this. This is the reason I always used Ruby and Watir for web automation (as opposed to GEB in the Groovy world.) But I can’t do it. The time sink here is too much. If I can’t get a simple cron / schedule of tasks going in Rails… then what?
Since I build tools that monitor environments using automation tools like SIPP, Sox, Web Automation (Watir/Selenium/etc.), I need a scheduling utility that works… Ruby/Rails doesn’t seem to have one.
Doing a little digging I found this: http://watij.com
WATIR-webdriver is my favorite browser automation framework (which I thought was exclusive to Ruby.) I’m going to check out this Watij and see if it’s any good. If it meets my needs (i.e. better then GEB) then I’m going to stick with Groovy/Grails and finally drop the last reason I was holding on to Ruby (Browser Automation.)