Rails Javascript and CSS Compression

July 30th, 2009 mindtonic No comments

To speed up site loading, there are two great plugins for “compressing” your stylesheets and javascript.

The first is bundle-fu. This plugin does not actually compress the files, but rather combines all of the individual documents into one before shipping it out to the client browser.

$ script/plugin install git://github.com/timcharper/bundle-fu.git

And then you simply wrap your sheet and script calls in the bundle method:

  <% bundle do %>
    ...
    <%= javascript_include_tag "prototype" %>
    <%= stylesheet_link_tag "basic.css" %>
    <%= calendar_date_select_includes "red" %>
    
    ...
  <% end %>

The Second plugin, which actually does compress all of your files, is sbecker’s asset_packager. This one is a lot more involved, so check out the github site for more information.

Calendar Date Select Magic For Rails

July 27th, 2009 mindtonic No comments

Calendar Date Select is a new(ish) “date and time picker”, developed by Tim Harper, designed primarily for developers to use in Rails applications. It uses the standard Prototype JavaScript library, and is easily installed as a Rails plugin:

script/plugin install http://calendardateselect.googlecode.com/svn/tags/calendar_date_select

The demo seems to be down, but here is some more detailed info: http://ianli.com/site/HowTo/UseCalendarDateSelectRailsPlugin. You can also see the original contents of the demo site about halfway down the Google Code wiki for the project: http://code.google.com/p/calendardateselect/wiki/CalendarDateSelect

On the surface this is a very easy plugin to install and use. It seems the common problem is that there is very little documentation available and the demo server is down. After installing the gem, I was able to run “gem server” and view the rdoc for the plugin. A couple of things I thought would be helpful to repost here:


Form Helpers:

calendar_date_select(object, method, options={})

Similar to the difference between text_field_tag and text_field, this method behaves like text_field

It receives the same options as calendar_date_select_tag. Need for time selection is automatically detected by checking the corresponding column meta information of Model#columns_hash

calendar_date_select_tag( name, value = nil, options = {})

Similar to text_field_tag, but adds a calendar picker, naturally.
Arguments

  +name+ - the html name of the tag
  +value+ - When specified as a string, uses value verbatim.  When Date, DateTime, Time, it converts it to a string basd off the format set by CalendarDateSelect#format=
  +options+ - ...

Options
:embedded

Put the calendar straight into the form, rather than using a popup type of form.

  <%= calendar_date_select_tag "name", "2007-01-01", :embedded => true %>

:hidden

Use a hidden element instead of a text box for a pop up calendar. Not compatible with :embedded => true. You‘ll probably want to use an onchange callback to do something with the value.

  
  <%= calendar_date_select_tag "hidden_date_selector", "", :hidden => "true", :onchange => "$('cds_value').update($F(this));" %>

:image

Specify an alternative icon to use for the date picker.

To use /images/groovy.png:

  <%= calendar_date_select_tag "altered_image", "", :image => "groovy.png" %>

:minute_interval

Specifies the minute interval used in the hour/minute selector. Default is 5.

  <%= calendar_date_select_tag "month_year_selector_label", "", :minute_interval => 15 %>

:month_year

Customize the month and year selectors at the top of the control.

Valid values:

 * "dropdowns" (default) - Use a separate dropdown control for both the month and year
 * "label" - Use static text to show the month and the year.

   <%= calendar_date_select_tag "month_year_selector_label", "", :month_year => "label" %>

:popup => ‘force‘

Forces the user to use the popup calendar by making it‘s text-box read-only and causing calendar_date_select to override it‘s default behavior of not allowing selection of a date on a target element that is read-only.

  <%= calendar_date_select_tag "name", "2007-01-01", :popup => "force" %>

:time

Show time in the controls. There‘s three options:

 * +true+ - show an hour/minute selector.
 * +false+ - don't show an hour/minute selector.
 * +"mixed"+ - Show an hour/minute selector, but include a "all day" option - allowing them to choose whether or not to specify a time.

:year_range

Limit the year range. You can pass in an array or range of ruby Date/Time objects or FixNum‘s.

  <%= calendar_date_select_tag "e_date", nil, :year_range => 10.years.ago..0.years.from_now %>
  <%= calendar_date_select_tag "e_date", nil, :year_range => [0.years.ago, 10.years.from_now] %>
  <%= calendar_date_select_tag "e_date", nil, :year_range => 2000..2007 %>
  <%= calendar_date_select_tag "e_date", nil, :year_range => [2000, 2007] %>

CALLBACKS

The following callbacks are available:

 * before_show / after_show
 * before_close / after_close
 * after_navigate - Called when navigating to a different month. Passes first parameter as a date object refering to the current month viewed
 * onchange - Called when the form input value changes

  <%= calendar_date_select_tag "event_demo", "",
    :before_show => "log('Calendar Showing');" ,
    :after_show => "log('Calendar Shown');" ,
    :before_close => "log('Calendar closing');" ,
    :after_close => "log('Calendar closed');",
    :after_navigate => "log('Current month is ' + (param.getMonth()+1) + '/' + (param.getFullYear()));",
    :onchange => "log('value changed to - ' + $F(this));"

}}}

All callbacks are executed within the context of the target input element. If you‘d like to access the CalendarDateSelect object itself, you can access it via "this.calendar_date_select".

For example:

  <%= calendar_date_select_tag "event_demo", "", :after_navigate => "alert('The current selected month is ' + this.calendar_date_select.selected_date.getMonth());" ,

For use with Form Builders

calendar_date_select(method, options = {})


Controllers:

In my application, I am using a custom form builder, so I used the calendar_date_elect with the form builder. The options hash appears to be the same as in the other view tags, so I just passed along what I needed:

<%= f.calendar_date_select "date", :embedded => true, :year_range => 1.year.ago..5.years.from_now, :time => false %>

I was pleased to discover that, utilizing some of the magic of Rails, the date property on my event was automatically turned into a datetime attribute, and on editing, was reloaded into the calendar as expected.

Categories: Gems, Ruby On Rails Tags: ,

Working With Server Processes

July 27th, 2009 mindtonic No comments

A simple little entry, I know, but a powerful tool to use and remember!

Display full information about each of the processes currently running.:

ps -ef

Output:
UID PID PPID C STIME TTY TIME CMD
hope 29197 18961 0 Sep27 ? 00:00:06 sshd: hope@pts/87
hope 32097 29197 0 Sep27 pts/87 00:00:00 -csh
hope 7209 32097 0 12:17 pts/87 00:00:00 ps -ef

To see just Ruby processes:

ps -ef | grep ruby

How to Kill Processes for a User

I had a BackgrounDRb process that just wouldn’t give it up, for a month, really! When all else failed, this worked:

kill -9 `ps -u username | grep -v PID | awk '{ printf ("%s ", $1); }'`

Replace username with the actual user name. Of course you should only use the -9 option when you really have to.

The New Way

Instead of going through all of that, you can simply use the pkill command if you already know the process name or part of it.

$ pkill packet_worker_runner

It’s as simple as that. You should note that pkill will kill all processes matching the search text, in this case backgroundrb processes which can be identified by the packet_worker_runner process name.

If you want to see what process names are matched before using the pkill command, you can use the ps command as described above.

$ ps -ef | grep packet_worker_runner

Categories: Development, Unix Tags: ,

Factory Girl stringify_keys error in Create Test

July 21st, 2009 mindtonic No comments

I was getting the following error while trying to test the create method of a controller using factory_girl and shoulda:

NoMethodError: undefined method `stringify_keys!`

The error was that I am sending an object to the create method, which actually requires a hash of attributes… the solution is to use factory_girl’s attributes_for method.

Hope this helps!

Categories: Development Tags: ,

Daemon Monitoring

July 21st, 2009 mindtonic No comments

Now that we are beginning to sort out some of our biggest issues, we are going to need daemon monitoring. I will elaborate as I work through the process, but for now this looks like a whoop-ass solution!

http://github.com/FooBarWidget/daemon_controller/tree/master

Categories: Development Tags: ,

Beginning the GIT transition

July 21st, 2009 mindtonic No comments

I know I am late to the party, as usual, nut after finding out about the great hosting option known as Heroku, it has become a necessity.

My one drawback is that I love my svn gui SmartSVN. It turns out that there is a built in GUI called git gui…. read here: http://pillowfactory.org/2008/09/11/git-awareness-week-git-gui/ for more info.

Other Resources:


So here we go with the process today. I found that this blog post http://blog.viarails.net/2008/4/4/how-to-convert-your-svn-repo-to-git was flawless in execution and I highly recommend it. So far I have been able to complete the transfer and upload the new git repository.

I would like to argue that SVN is not passé – or out of style – in fact when you are working with a small team of developers, or even by yourself, I think that the remote server concept is actually quite beneficial. I understand the whole branch / merge concept, and think it is fantastic, but I see value in all both approaches. Just my 2 cents.

Categories: Development Tags:

Experiments in Rails Process Scheduling

July 8th, 2009 mindtonic 1 comment

I need a way to call a process on a regular basis inside of my Rails application. I have been working in and around this idea for over a year and have tried several different methods.

One thing to mention is that CRON jobs are an obvious solution to these problems. However, as I am serving off a Joyent server, I have had difficulty setting up my CRON jobs and getting them into the right file with the right RAILS_ROOT settings to my application files. If anyone knows a good way to set these up on Joyent, please let me know!

I have been reading several excellent blog posts, including Igvita.comhttp://www.igvita.com/2007/03/29/scheduling-tasks-in-ruby-rails/, and the Rails Wiki itself – http://wiki.rubyonrails.org/howtos/background-processes.

Rufus Scheduler

My current attempt is to try Rufus. I highly recommend that you examine the article Dead simple task scheduling in Rails by Brent Collier.

You can find the online documentation for the Rufus-Scheduler here: http://rufus.rubyforge.org/rufus-scheduler/

The first error I encountered in my odyssey was:

config/initializers/task_scheduler.rb:6: undefined method `start_new' for Rufus::Scheduler:Module (NoMethodError)

This was caused because I didn’t include the rufus/scheduler line at the top of my config/initializers/task_scheduler.rb file:

require 'rufus/scheduler'

I only include this oversight in case someone else happens to encounter the same error in their code.

Back To BackgrounDRb

Rufus Scheduler worked great for the simple tasks, but some of what I am trying to do has the potential to take up a lot of time. The problem I encountered with rufus was that as the time requirements grew, it was taking more and more instances from my mongrel cluster, eventually drawing the server request/response cycle to a complete stop. Not good when you are trying to host a public site!

Because I know that these processes can be time consuming, they need to be relegated to a separate server instance. So I am returning to BackgrounDRb.

My previous experiences with BackgrounDRb produced the following opinion from my own blog post:

I really like the theory and concept behind BackgrounDRb, but it seems to be a bit overkill for what I am trying to accomplish. Also, it was almost impossible to keep the BackgrounDRb server running, even with the use of Monit. There just always seemed to be something that was crashing our beloved process.

Learning from my previous experiences, I have thoroughly tested and retested the code that will be called from my workers. I am setting things up to run using the add_periodic_timer method as my first attempt. On my local machine, everything seems to be working fantastically. I plan to set everything in motion on my production server tonight and see where we sit in the morning.

The First Results

I am happy to report that with the proper configuration, and the strategic placement of begin .. rescue Exception code, BackgrounDRb is successfully performing the functions I require!

One comment that I have is that it is difficult to figure out what it is doing when. To counter this issue, I have designed a very simple background_logger to monitor the processes and let me know when things start and stop.

To do this, you first make a class for the BackgroundLogger:

From lib/background_logger.rb:

class BackgroundLogger < Logger
  def format_message(severity, timestamp, progname, msg)
    "#{timestamp.to_formatted_s(:db)} #{severity} #{msg}\n"
  end
end

Then you add awareness of this logger in your environment file:

From config/environment.rb:

background_logfile = File.open("#{RAILS_ROOT}/log/background.log", 'a')
background_logfile.sync = true
BACKGROUND_LOG = BackgroundLogger.new(background_logfile)

This adds a contstant called BACKGROUND_LOG that you can then use in your workers:

From lib/workers/foo_worker.rb:

class FooWorker < BackgrounDRb::MetaWorker
  set_worker_name :foo_worker

  def create(args = nil)
    BACKGROUND_LOG.info("Foo Worker Started")
    add_periodic_timer(5400) { do_foo }
  end

  def do_foo
    BACKGROUND_LOG.info("Starting Foo...")
    MyModel::do_foo
    BACKGROUND_LOG.info("Foo Done!")
  end
end

The resulting log output will include timestamps and such that can help you keep track of what is going on, when it happens, and in the event of a hiccup, let you know when it happened and in which file. This is of course in addition to the information provided in BackgrounDRb’s own logs.

So, BackgrounDRb is NOT the answer… what else is there?

Everything was peachy until my processes gre to be very large in number. Not good when it takes so long to do something that the machine chokes and it all grinds to a halt!

So what are my other options? Turns out that now everyone recommends delayed_job, a plugin from shopify that does the same thing only better. The folks at Engine Yard highly recommend delayed_job over backgrounDRb due to severe memory leaks and other not so favorable conditions.

I am happy to report that the results are excellent! Without even having Monit or God running, delayed_job has been kicking serious butt on my project. I think I’ll stick with it for awhile.

Monitoring All Of These Processes

The next part is to explore how to keep it all running when I run off to play music for the weekend. I know that Monit is a common choice, and having read up about it, it might be the best option. I am however, going to start with a different option… you can follow my progress in this area from my Daemon Monitoring blog post.

Cheers!

Categories: Gems Tags: , ,

Available Fields from FeedNormalizer Gem

July 8th, 2009 mindtonic No comments

The FeedNormalizer Gem does an excellent job of returning a single unified object from many of several different syndicated feed types. This saves you from having to worry about whether you are dealing with an rss, atom or some other kind of feed.

The following is a list of the available fields for both the Feed object itself and the Entries objects associated as articles in the channel.

FeedNormalizer::Feed

  • title
  • description
  • id
  • last_updated
  • copyright
  • authors / author
  • urls / url
  • image
  • generator
  • items / channel

FeedNormalizer::Entry

  • content
  • description
  • title
  • date_published
  • urls / url
  • id
  • authors / author
  • copyright
  • categories

Etags

Etags and last_modified are crucial elements to sending proper request headers if you hope to receive conditional get responses and save yourself some overhead in feed processing. FeedNormalizer does not provide access to these elements as they are actually part of the http response headers, and not the feed itself.

While heavily studying the art of feed processing, I encountered Feezirra and Feedtosis, both excellent libraries for feed processing. My own application required a modified version of their concept, but there was a lot to learn in their code.

Feedtosis uses the HttpHeaders process to collect this information from a Curl::Easy object. I adapted the Feedtosis code to meet my needs like this:

require 'http_headers'

class Feed < ActiveRecord::Base
  def store_header_information
    headers = HttpHeaders.new(curl.header_str)
    self.response_code = curl.response_code
    self.etag = headers.etag unless headers.etag.nil?
    self.last_modified = headers.last_modified unless headers.last_modified.nil?
  end
end
Categories: Gems Tags: , , ,

How To Start the Gem Server for Local Gem Rdocs

July 8th, 2009 mindtonic No comments

To view the rdoc documentation for all of your locally installed gems, at the command line run:

$ gem server

This will start the gem server at port 8808, so to access the html from your browser, use the following url:

http://localhost:8808/

Note that this only access the documentation for Gems that are installed locally on your server.

Categories: Gems Tags: ,

Unit Testing Object Oriented PHP5 Code

July 1st, 2009 mindtonic No comments

I have been doing a lot for work with testing and development in Ruby. This has lead me to want to find an option to write Unit Tests for my own PHP based Content Management System, Shabda. It would be a very wise move to make sure that the core system files function exactly as expected. I will update this blog post as I go along.

My research has yielded two possible testing options:

SimpleTest

Other blogs with more information: http://vailo.wordpress.com/2008/07/03/php-unit-test-test-driven-development/