Archive for the ‘Padrino’ Category

Even Faster XML Parsing

Saturday, January 28th, 2012

I wrote Fast XML Parsing in Ruby over last summer. It has a number of optimizations in it, including combining a bunch of string compares into one regular expression (regex) compare. It has bothered me it still does a series of bunch of string and regex compares, one after another until a match. They could be combined into one (unreadable) regex, if there was a simple (and fast) way to determine which matched. Right now each regex or set of strings has a different action. A single regex could cover all the valid matches, but how to determine which action?

I mentioned creating a Domain Specific Language (DSL) for this situation. But there is already something like this, YACC (Yet Another Compiler Compiler). It has been around for decades in the Unix world. YACC handles LALR(1) languages. Regular expressions are a subset of LALR(1) languages.

Bison is an open source version of YACC with some additional features. Rbison claims to merge Ruby and Bison to produce a Ruby callable YACC parser (in C) with actions written in Ruby. A great solution, except it has been abandoned by it creator and his repository taken down. Rbison 0.0.7 is in a number of FreeBSD repositories. I looked at it and it shows some work was done, but it is a long way from being usable. The goal may be too ambitious or even impossible.

Racc is YACC written entirely in Ruby. It is usable and I am working on using it speed up the RSS and OPML parsers described in the article. The OPML parser is working – it passes the test suite and doesn’t blow up running the examples. I haven’t pushed it to github yet. I haven’t run any benchmarks yet, but my current thinking is that it will not be faster. It is pure Ruby, while the Ruby regex library routines is in C. I expect it can match a bunch of regex faster than a single Racc parser.

I expect to have the RSS parser converted to use Racc in the next few days. I’ll post the benchmark results when complete, which ever way they turn out.

ActiveRecord callback methods deprecated in 2.3.8

Saturday, January 21st, 2012

According to this, instance callback instance were deprecated, starting in Rails 2.3.8. An instance callback method is like this:

class Item < ActiveRecord::Base
  def before_create
    # whatever
  end
end

By ActiveRecord 3.1.3 (used in Padrino 0.10.5), instance callback method support is gone. The supported way to do the above is:

class Item < ActiveRecord::Base
  before_create :set_defaults

  def set_defaults
    # whatever
  end
end

ActiveRecord (AR) had two or more incompatible ways to specify callbacks: instance methods (1st example) and callback queues (2nd example). If you have inherited AR classes (e.g. AdminUser is a child class of User, which is an AR) the instance method of the parent class is overridden and never called from child class instances. With callback queues, all callbacks are called. Current practice is described in ActiveRecord::Callbacks

In the Rails version of AmethystRSS.net, I'm using Rails 2.3.14 with instance callback methods, but not seeing any deprecation warnings. Not sure why.

Padrino/Sinatra and AuthLogic

Thursday, January 19th, 2012

AuthLogic 3.1.0 doesn’t play nice with Sinatra 1.3.2. The error message is;

`included': undefined method `before' for Sinatra::Request:Class (NoMethodError)

The solution is to patch the last line of authlogic-3.1.0/lib/authlogic/controller_adapters/sinatra_adapter.rb from:

Sinatra::Request.send(:include, Authlogic::ControllerAdapters::SinatraAdapter::Adapter::Implementation)

to:

Sinatra::Base.send(:include, Authlogic::ControllerAdapters::SinatraAdapter::Adapter::Implementation)

Thank you to the post here (Google translation here)

Rails2 to Padrino – What to Change?

Wednesday, January 18th, 2012

It is tempting to do some substantial rewrites during migration to a new platform. Experience has shown that it is rarely a good idea. Just the migration itself is enough disruption – ActiveRecord (AR) and ActiveSupport 2.3 to 3.1, Rails controller syntax to Padrino/Sinatra, Ruby 1.8.7 to 1.9.2 and the string encoding issues.

As mentioned in a previous post, I did benchmark some of the alternatives. ERB to Erubis is a minor change. I have already migrated from the Prototype Javascript library to jQuery’s compatibility mode. As templates are edited, I’ll move to jQuery native mode and make use of jQuery Unobtrusive JavaScript (UJS).

I’m tempted to move to more or all rendering and some data caching on the browser with the server just rendering JSON. That will wait until after the migration to Padrino.

Approaching Rails2 to Padrino Migration Go/Nogo

Wednesday, January 18th, 2012

I ported a very minimal part of AmethystRSS.net to Padrino. It looks good. Before I really start full-time, I tried out a few alternatives. Amethyst has an inherent responsiveness problem, e.g. rendering 300 partials with 5 links and a couple of bits of text while the user waits. Caching helps, the second time they access the list. And the list ages rapidly, 50-70 new items a day. Wait three days to check your RSS feeds and all 300 are new.

So I benchmarked some of the alternatives – 300 items, each with 2 links and a couple of bits of text in a zebra-striped table (CSS courtesy of Twitter’s Bootstrap project), MySQL (w/ mysql2 adapter), 2700+ items in the DB. Response times are measured in Firebug, i.e. end to end as seen from the browser, both it and the server on the same laptop. HAML is 8% slower than ERB. ERB is 2% slower than Erubis. DataMapper is 7% slower than ActiveRecord 3.1. This last one is a bit surprising. I’m going to dig into it a little more. Plus figuring out how to store all times in UTC and display them in the user’s local time in DataMapper.

None of the performance differences are deal killers. My templates are ERB, I’ll leave them that way. My models are written for ActiveRecord 2.3.x. I’ll stick with it unless I find out how to achieve a lot more speed with DataMapper.

If you select HAML during project generation, ERB is available too. This suggests the possibility of fast prototyping in HAML and converting frequently used templates to ERB when stable.

Character Encoding w/ Padrino, AR, MySQL, and Ruby 1.9

Friday, January 13th, 2012

Exceptions were occasionally occurring in Padrino: Encoding::CompatibilityError - incompatible character encodings: UTF-8 and ASCII-8BIT:. This is with Ruby 1.9.2. Googling the error message turned up plenty of hits, none of them helpful. Trying the same thing in the Padrino Framework Google Group was more helpful, but a key piece of information was missing. Or since the posts were a year and a half ago, things changed. The mysql gem encodes all strings as 8BIT ASCII! Even if the database is UTF-8. Switching to the msyql2 gem and setting the adapter to mysql2 in config/database.yml solved the problem. If your don’t set the adapter correctly, Padrino complains about stack too deep. I encountered the same stack overflow with ruby-mysql.

Setting DB Timezone in Padrino

Wednesday, January 11th, 2012

All timestamps in Amethyst’s database are in UTC.  Out of the box, Padrino and ActiveRecord assume they are in the local timezone. There may be a better way (i.e., ORM agnostic), but this works for ActiveRecord.  In config/boot.rb:

##
# Add your before load hooks here
#
Padrino.before_load do
I18n.locale = :en
ActiveRecord::Base.time_zone_aware_attributes = true
ActiveRecord::Base.default_timezone = :utc
end

The first assignment sets the default locale (found this in the Padrino Localization guide).  The next two are ActiveRecord specific.  I dug into the Rails lib/initializer.rb code to find them.

Investigating Padrino

Wednesday, January 11th, 2012

Rails 3 has outgrown my needs.  I spent a day and a half trying to migrate Amethyst from Rails 2.3 to Rails 3.0 and didn’t appear to be any closer to being done.  And I encountered a number of Rails3 bugs and/or incompatibilities that had no obvious fix.

Watching Rails 3 development, I see it creeping down the slope of being all things to all Web developers with lots of new, shiny thrown in for good measure.  There are a lot of moving parts.  (I need to install a Javascript interpreter?  Really?)  Rails3 was supposed to be much more modularized and configurable, cherry picking just the pieces I need, but I may have to install everything and then try and back out unneeded pieces.

Rails was originally developed by someone writing lots of Websites.  They climb the initial, steep learning curve once and then can crank out product at a ferocious rate.  The Website part of Amethyst is relatively straight forward.  It’s the scoring and the backend (i.e., non-Rails parts) that are the secret sauce.  And much of the Rails2 and Rails3 magic costs too much in terms of user response times (i.e. the routing magic – I’ve reverted to string interpolation for URLs).

I’m investigating migrating to Padrino, a Web framework built on top of Sinatra.  Padrino claims to be 3-5 times faster than Rails.  My first cut using the simplest usable piece of Amethyst (viewing the articles in a whitelisted subset of the RSS feeds subscribed to) is appropriately twice as fast.  But it doesn’t yet have pagination or caching.  I expect the former to slightly slow it down and the former to significantly speed it up.  I’ll be blogging on my progress, the problems I encounted (and solutions when I find them), and how satisfactory I find Padrino.