Archive for September, 2008

RailsConfEurope: I heart complexity

Last talk I followed today was titled “I heart complexity” by Adam Keys (http://therealadam.com/). It turned out to be quite an interesting talk.

Rails was designed to be as simple as possible, but sometimes you just have a complex application domain. Adam looked into making complex problems more tractable by splitting them up.

His approach:

1. Domain modelling
Domain Driven Design. Bring programming language up to level of domain (DSL?), and vice versa to the point where they meet. This will result in an ubiquitous language, which reduces the amount of documentation you will have to write. This is expressed in your code as Entities (e.g. ActiveRecord models), Values (these are the glue /metadata, non unique things e.g. money), Services (they tie things together to get things done, e.g. routingservice). Then focus on the essence: essence = domain + intention. This will result in less ceremony of your technology.

2. Stateful logic
Instead of flags, use a statemachine (e.g. use the AASM plugin)

3. Monies
Don’t use floats, use a Money object with currency and cents (integer). Tthere is a Money gem for this that can even convert between currencies.

4. Time Travel
You could use something like acts_as_versioned.

5. Asynchronous Processing
You could use a message queue for this.
Adam shows an example of keeping track of moderations to a product catalog that need to be approved. Instead of a messagequeue he uses a statemachine to model a queue. Nice example.

Resources

AASM plugin (state machine)
Money gem
acts_as_versioned

RailsConfEurope: How NOT to build a webservice

After a confusing and weird talk called Treading the Rails with Ruby Shoes by Eleanor McHugh and Romek Szczesniak (note to self: remember these names, I had the same weird experience with these people at RailsConfEurope 2006), I followed a talk titled How Not to Build a Service by Mike Perham of FiveRuns.

Quite an interesting and honest talk about the lessons they learned from building a (paid) webservice (a monitoring webapp for Rails apps). You can read the details in the slides. Worth the read if you ever want to run a startup that develops a product, but also if you develop a product for a client.

Interesting point he made was that you have to recognize when you are making a decision, keep track of them (e.g. document them) and determine your level of ignorance (how much do / don’t you know). Then determine what level of ignorance you are comfortable with / can afford.

Another intersting point he made was about groupthink (e.g. the whole group acts on the believes of a performance expert, but the expert does not have expertise on webapps. Then the group could obsess over the performance on the serverside, but looking at the images / css + js files / browser cache will make a much bigger impact on your webapps performance! See also post on Jeremy Kemp’s keynote).

Resources

Slides: later on conference site

RailsConfEurope: Advanced RESTful Rails

Next session was Advanced RESTful Rails by Ben Scofield of Viget Labs, which turned out to be an interesting in depth talk about advanced REST concepts and how to implement them in Rails. This talk and the talk RESTful Everything – Towards a Complete Resource-oriented Workflow yesterday, reignited my interest for REST (it kind of faded out a bit lately).

REST is basically about two things: resources (which don’t have to map to tables / models) and representations (each resources can have different representations e.g. book/1, users/1/favoritebooks/2).

RAILS implements REST quite nicely. Ben discussed some more advanced REST techniques that aren’t know very well or that are not used very often:

- singleton resources (e.g. for session, profile, password (for current user), search)
- namespaces (e.g. to group admin stuff)
- nesting
- polymorphism (e.g. “map.resources :user, :has_many => [:readings]” and “map.resources :book, :has_many => [:readings]“.
- custom routes (changing url’s and getting to views with a nice url)

There are a couple of plugins that try to DRY up RESTful controllers:

- resource_this
- resources_controller
- make_resourceful
Ben Scofield finds them too much magic and prefers to see the actual REST code. I tend to agree with him.

Modelling advice
Ben’s tips on how to get from a messy domain to a nice set of RESTful resources:
- identify resources
- select HTTP verbs to expose
Some tips:
- when in doubt, add a resource (you can also roll it up later = easier)
- respect the middleman (join models)
- resources != models

Examples:
- homepage /dashboard might be the index of a resource (look what it’s function is)
- Search: over a single resource then add filter with query param to index. Multiple resources? Then use a new (non-db) model (e.g. Searcher). Most cases you should use GET.
- Wizards (see slides)
- Bulk actions: Rails REST doesn’t handle bulk actions on resources well. Just override the normal map.resource with a custom route! (see slides)
- Transactions: can also be moddeled RESTfully (
- Administration: also no problem (use map.namespace, http basic auth)

Stumbling blocks (for Rails)
- Rails helpers (e.g. link_to … method => ‘delete’) are not very accesible
- default routing (in bottom of routes.rb) overrides all RESTful routest (they are not protected anymore). So remove it
- unused actions (e.g. formatted variations)
- collections (see previous comment on Bulk Actions)
- ARes Avalanche (always check server log)

At the end Ben also mentioned a couple of framework that might be worth looking at in the context of REST: Sinatra, Waves and Halcyon.

After the presentation I asked Ben for some advice for refactoring my controllers to be more RESTful. He gave some really good tips. Thanks for that Ben! If I implemented the RESTful controllers I might write a separate post on how I did that. I also bought the book RESTful webservices by Leonard Richardson and Sam Ruby, so it won’t be a long before I will be a REST guru too :)

resources

http://www.viget.com/extend

http://www.culann.com

RailsConfEurope: Design on Rails for Usability

First session I followed today was a session called Design on Rails for Usability by Christian Lupp of codedifferent.

Christian is a designer and talked about the concepts and worflow of designing (or in his words, solving a ‘wicket problem’). Nice to hear the perspective of a designer on Rails. He also had some nice advice for us developers. Might be useful in working with the designers at the company I work for:

- if there are two equal solutions .. take the easier / simpler one (Okcham’s Razor). You could try to reduce funtionalities until your customer thinks the application is missing something. Then, go one step back.
- designers should learn more about the possibilities of Rails, Javascript etc. so they new what is possible when designing the interaction. They should also take a more central role in interaction style.
- developers should learn more about interaction design!
- make your webapp accesible (not only so that everyone can use your app, but also for SEO and performance reasons)

Accessibility can be reached by:
- separating html, css and behaviors (JS / LowPro)
- repeat structures by DRY – recognizable patterns (like chapters, pagenumbers, footnotes, footers / headers in a book). Layouts and partials of Rails are really useful here.
- validate inputs and give feedback
- give feedback with Rails flash messages
- don’t let the user wait .. keep him busy! (“Schiphol problem” – users prefer to walk 10 minutes and pick-up their bags immediately over walking 2 minutes and wait for 8 minutes for their bag). Search form example: search form, extra search proces (e.g. ask how results should be sorted etc. to keep user busy), then show results! If you can’t do that, at least give some feedback (e.g. search will take some time).

RailsConfEurope: last day :(

Already the last day Railsconfeurope in Berlin. Until now it has been a really good conference, so today should be good as well (I hope ;) ).

The day started with a plenary discussion on Ruby versions and implementations. I am not that interested in Ruby version (I just use the mainstream stable version) but the new features of Ruby 1.9 look really promising.

RailsConfEurope: Performance on Rails (keynote Jeremy Kemper)

Tonight’s keynote at RailsConfEurope 2008 was “Performance on Rails” by Jeremy Kemper of 37signals.

In the upcoming Rails2.2 release there are a lot of minor changes, not really big paradigm shifting changes. One of the things the core team has focused on is performance.

What is performance
Jeremy first asks the question “what is a performant application?”. To Jeremy a performant application is snappy for it’s users (it’s all about the user experience). To make the application snappy you could prematurely optimize your Rails app’s code, add more hardware to it etc.

Focus on the front-end first
It is more effective though to focus on the front-end / browser first;:

- look what is pulled to the client: firebug network tag, YSlow (checks rules at http://developer.yahoo.com/performance/rules.html)

- add expire headers (e.g. for all your assets with ExpiresActiveOn or FileETag in Apache), combine js and css files etc. (rails has facilities for this)

- multiple asset host (e.g. with config.action_controller.asset_host = “asset%d.myapp.com” in your Rails config)

- try not to put javascript inline, but use unobtrusive javascript (e.g. LowPro)

but the most useful thing is to look if your app can do less

Then measure and improve your Rails app
When you have done all that, then you can look at your Rails app. For this you need instrumentation. Where is the time spent, is it my Rails app, the database, the web?

- A nice new tool for this is New Relic RPM (overall performance)
- Another tool is FiveRuns TuneUp (code profiling)

- script/performance/request (shipped with Rails2.1 >), which plays an “integration test” script. Is a bit ad-hoc and results are hard to interpret. Following tool is more useful:

- Rails2.2 will support performance tests (/test/performance/*_test.rb) . Can be run with “rake test:benchmarks”. Saves results in csv file so benchmarks can be plotted over time and different ruby versions can be compared.

Another way to optimize is “conditional GETS” which fits nicely with the Rails REST philosophy. Works with Last-modified and ETag headers, which you can set yourself in the controller (see slides for examples), but Rails2.2 (I think it’s not in 2.1 yet ?) has support for this.But what about caching proxies? Jeremy admits that he might not know enough about them, but might be interesting for Rails apps.

Fixing the Garbage Collector
Another area that can be improved is the ruby garbage collector. This is setup for short lived processes, but in webapps the processes are long lived. Luckely there is a patch for the Ruby GC that lets you tweak it.

http://github.com/skaes/railsbench

For a typical webapp Jeremy recommends the following settings (to be sure, check the slides!):

RUBY_HEAP_MIN_SLOTS=6000000
RUBY_HEAP_FREE_MIN-100000
RUBY_HEAP_MALLOC_LIMIT=60000000

According to Jeremy this wil give you a (almost) free performance boost, so that might be worth looking into.

Caching
Problem is generating good cache keys (“Expect to get it wrong”).
So try to design for cacheability (see slides)

Rails performance?
To Jeremy the most performance gains can be found outside Rails (browser, caching etc.).

Resources

Slides: later on conference site

RailsConfEurope: RESTful Everything – Towards a Complete Resource-oriented Workflow

Didn’t really know what to expect from this session, but it was really good (both content and presentation).

The session was titled RESTful Everything – Towards a Complete Resource-oriented Workflow and was presented by Ingo Weis.

abstract from the conference site:

“Rails’ RESTful routing facility provides developers with conventions for naming controllers and controller methods. However, Rails fails to keep up the RESTful momentum beyond controllers. This presentation is about all the good things that happen when picking up where Rails left off and establishing resource-oriented conventions for helper names and CSS classes.”

Ingo explained what is missing in Rails at the moment for a truly RESTful webapp and demonstrated a plugin he developed that complement the rails helpers for RESTful routing. I think that the helpers of this plugin produce very clear, readable and compact views. Another advantage is that they helpers produce really consistent html class and id attributes so that styling and attaching javascript behavior becomes a lot easier too. This way developers and designers get a common vocabulary (something we could really use at the company I work for). Really nice!

As a bonus, Ingo also showed a really nice way of making a google map accessible to users without Javascript: make a list of the locations with the geo microformat, select these locations with javascript and put them on a Google map. Really nice :)

I am definitely going to look into this plugin and this way of writing my view templates. Maybe hold an internal presentation for our designers too.
Resources:

slides: later on conference site
rails plugin: http://svn.ingoweiss.com/plugins/resourceful_views/tags/REL_0_1/resourceful_views/

RailsConfEurope: Intellectual Scalability

After the lunch (which was very good, just as yesterda) I followed a session with the title Intellectual Scalability – Solving a Large Problem With Multiple Cooperating Rails Apps by Frederick Cheung and Paul Butcher of Texperts.

Interesting idea of dividing up a complex application into several simpler applications. The applications run on their own servers and have their own database. Applications communicate on the back-end via RESTful API’s, on the front-end they communicate via AJAX. All applications are “widgets” loaded by AJAX calls. Works a bit like a portal.

The company that the speakers work for (Textpert) want to opensource their framework. Might be interesting when they do. Their solution seems to be a bit javascript heavy they, which might be a problem for some webapplications (e.g. if they need to be accessible).

Resources:

Slides: will be published on conference site

Next Page »