Category Archives: rails

Staying Alive with Thin!

TravoltaThin was the first Ruby server to be able to connect to UNIX domain sockets, giving you a little more speed, so you could spend less time browsing and more time dancing and eating ice creams with the people you love. But only Nginx (that I know of) supports UNIX domain sockets. Non-Nginx users might like to have time to dance and eat ice creams with the people they love too!

So that’s why Thin new release (0.7.0 codename Spherical Cow) supports persistent connections (aka Keep-Alive).

Apache & mod_proxy

Under Apache, if a client requests a persistent connection, the connection to the backend server (through mod_proxy) will also be persistent. That means the time spent opening the connection is saved for subsequent requests because all requests will be sent through the same connection. Even cooler is that you have nothing to do to set that up, unless you’ve turned Keep-Alive off.

I ran some benchmarks and I got an average gain of 200 req/sec with Keep-Alive on.
Keep-Alive benchmark

Sadly Nginx doesn’t support persistent connections to backends yet, but it seems to be a highly requested feature, and Igor Syseov (author of Nginx) said he’s working on it several times on the mailing list. Imagine that: UNIX sockets + persistent connections, oooh man!

Hey we develop too, sometimes!

Of course you’ll take advantage of that feature when it’s just you, Thin and your browser. And we can also benchmark it, just for fun, to get numbers that are sure to give you goose bumps: 7800 req/sec is just, ooooh, aaahh, hummm, yeah, that was good!

Keep-Alive

Swiftiply

If you’re looking for even more speed. Thin can now be used as a Swiftiply client. And it’s very easy to use:

thin start --servers 3 --port 8000 --swiftiply

Just add the --swiftiply option. This also means that any Rack adapter can be run through Swiftiply (using the --rackup option) including Ramaze, Camping, Merb, YourCrazyLittleFrameworkThatIsSoooBetterThenAllTheOtherAndThatSupportRack etc.

Speed with control

But what is speed with no control, right?

The main reason why Mongrel couldn’t support persistent connections was because of Ruby 1024 file/socket descriptors limitation. If you don’t close the connection (keep them alive) it’s one less descriptor you can use to process another connection or open a file.

Although EventMachine doesn’t have an infinite number of file descriptors it was reported to handle more then 20 000 concurrent connections.

You can now tune the number of connections a Thin server can handle.

--max-conns: This sets the maximum number of concurrent connections your Thin server can handle. Setting higher then 1024 might require superuser privileges on some system.

--max-persistent-conns: This sets the maximum number of persistent connections your Thin server can handle at the same time. If resource usage is important, you might want to turn that down. You can turn Keep-Alive support off by setting to 0.

Get it!

Spherical Cow also comes with a couple bug fixes and tweak.
As usual, you can get the latest version from RubyForge:

sudo gem install thin

If you have any question, join the Google Group or the #thin channel on freenode.

I hope you like it!

16 Comments

Filed under rails, ruby, thin

MoR7 Presentation

ImageHere’s the code and slides of my presentation : http://github.com/macournoyer/mor7/

Hope you liked it!

1 Comment

Filed under montreal, rails, StandoutJobs, thin

Has Zed jumped the shark ?

Zed ShawZed Shaw, the creator of Mongrel, is writing some pretty nasty stuff about the Rails community, ThoughWorks and Ruby.

There’s no work for a smart man in a town full of stupid.

Although I agree there might be some stupid people working with Rails right now, there’s a huge number of very bright people too. And there’s stupid people working with PHP, Java, Python, C, Haskell, Erlang, Lua and Factor too.

The thing is: Rails is getting easier to use every day, lowering the barrier of entry for new coders. The Rails community is growing beginner level coders a lot faster then expert coders now. A year ago, it was probably the opposite. Alpha geeks like being credited for doing hard stuff, solving impossible puzzle, and making code run faster then you could think possible. But Rails is so standardized now, there’s little place for innovation. So new coders to make a name in that community by changing the game again. It was easy before, nothing was there, everything was to be done!

Congratulations because all the idiots who paid ThoughtWorks 6x times salary for junior ass wipes got taken and simply paid to train ThoughtWorks’ new crew

And maybe ThoughWorks is taking advantage of Rails popularity, but it will happen for other cool framework/language too if they get some day to that level of popularity. There’s no reason to shit on the Rails community for this.

After revitalizing myself, getting out of the Rails business (or trying), distancing myself from Mongrel, disconnecting from the Ruby community

Is this the end of Mongrel ?

Zed rant was pretty excessive and even though he claims that everything he writes on his blog is an act, I’m sure he’ll regret this as this will get quoted out of that so-called humorous context.

Strange way to start the new year!

What’s your thoughts on this ?

16 Comments

Filed under rails, ruby

Getting TextMate ready for Rails 2.0

After updating a couple of existing Rails app to 2.0, I found out some of TextMate sugar was out of date. Here’s 2 things I did to put the hot and sweet sugar back into TextMate.

Update the bundle

TextMate bundles are under heavy development all the time, get the latest version from their repo:

svn export http://macromates.com/svn/Bundles/trunk/Bundles/Ruby%20on%20Rails.tmbundle

Then double-click on the downloaded Ruby on Rails.tmbundle.

Fix the test commands

I’m a heavy user of Run (command+R), Run Focused Unit Test (shift+command+R) and the Rails menu (shift+ctrl+\) but that do not work with Rails 2 because of a conflict with the builder module.

Rob Sanheim explain how to solve this very easily, just rename the Builder.rb in the Rails bundle.

Hope this helps!

15 Comments

Filed under rails, tips, tutorial

Rack, the frameworks framework

RackWith all the Ruby frameworks popping up, we’re starting to see some similarities. All of them provide something new or unique but one part of their code is always the same. The part that plugs it into a web server. Ultimately, all web servers have to support all frameworks and vice-versa. That is a lot of duplicated code! That makes me yell, running in circles, waving my arms: not DRY, not DRY, not DRY!

What?

Rack (not the iRack) by Christian Neukirchen, solves this problem.

From Rack website:

Rack provides an minimal interface between webservers supporting Ruby and Ruby frameworks.

Rack looks like this in my head:
Rack

Handlers on the left (web servers) serve requests to Adapters (frameworks) on the right.
(Don’t ask me what the rabbit is doing there, must be important)

Run Forest!

But Rack can do a lot more then plug Ruby framework into webservers. It is a framework in itself.

When you install it:

sudo gem install rack

You get the rackup command. Which lets you start your app on any supported web server.

require 'rack/lobster'

run Rack::Lobster.new


– config.ru

Start your app: rackup -p3000 then browse to http://localhost:3000, oh the cute lobster!

To run it on other web servers (mongrel by default) play with the -s option.

It’s a framework I said

The Handler API is only 1 method: call(env). Which allows you to use proc as application.

app = proc do |env|
  [200, { 'Content-Type' => 'text/html' }, 'no pepper plz!']
end
run app


– config.ru

That will return a 200 OK response with the text/html content type and the body no pepper plz!. env contains the request parameters, so you could play with the QUERY_STRING or wrap it inside a Rack::Request and get a request param value with request.params['name'].

Plug

You can use middlewares to filter the process. For example, you can add logging and detailed exception support with those 2 lines in your config.ru file:

use Rack::CommonLogger, STDOUT
use Rack::ShowExceptions

You can also validate your application, the requests and responses according to the Rack spec automatically using the Rack::Lint middleware.

(There’s also a Reloader, Static, Cascade, File and much more middlewares, check the doc)

You can also have fun with urls:

map '/files' do
  run Rack::File.new('.')
end

map '/lobster' do
  run Rack::Lobster.new
end

Check it out!

Rack is the best example of a very well design Ruby library. The code is simple, well separated and yet, easily extensible, it’s beautiful! I encourage you to check out the code but mostly to use it if you’re building any Ruby web framework (like we need other one!).

18 Comments

Filed under rails, ruby, tutorial

Rontreal On Mails is torromow

Snow make use slowMontreal is white and snowy
Ruby is red and pretty
Rails is red (also) so lets party

2 Comments

Filed under montreal, rails, ruby, StandoutJobs

Defensio launched

Remember my Defensio plugin ? It is used on RefactorMyCode to keep the site clean of any spam and the users happy.

Defensio(hit refresh if you don’t see the new site) is now public, so you can get an API key in seconds and get to speed with my plugin in milliseconds (or less).

Congrats to the Karabunga guys!

Here’s a screenshot of my stats window:

Defensio Stats

Pretty cool!

And you can also subscribe to a feed, so you get notifications of spam in your feed reader.

11 Comments

Filed under montreal, rails, refactormycode

Moving to Rails 2.0

I know … it’s like exercising, you know you’ll be better afterwards but you don’t feel like going trough the pain right now. Updating a framework can be a pain, here’s a short list summarizing what I had to do to migrate RefactorMyCode from Rails 1.2.3 to 2.0 (Preview). I hope this makes it easier for you!

0. Pistonize it!

Instead of using the classic way of freezing Rails in you app tree (rake rails:freeze:edge TAG=rel_2-0-0_PR), I’d recommend using Piston:

piston import http://svn.rubyonrails.org/rails/tags/rel_2-0-0_PR/ vendor/rails

This way, you’ll be able to make changes to Rails code and keep them while updating your copy!

1. Update your stuff

Update configs, scripts and javascripts:

rake rails:update

2. Move your session config to environment.rb

Add this in your environment.rb and remove the session ... line in application.rb:

# Your secret key for verifying cookie session data integrity.
# If you change this key, all old sessions will become invalid!
config.action_controller.session = {
  :session_key => '_app_name_session_id',
  :secret      => 'your secret key'
}

To compute your secret key:

require 'digest/md5'
puts [now = Time.now, now.usec, rand(0), $$, 'you_app_name'].inject(Digest::MD5.new) { |md5, e| md5 << e.to_s }

3. Split environment.rb

Rails now recommend putting your specific config code in config/initializers. Move everything outside Rails::Initializer.run do |config| ... end into separate files. For starter, create config/initializers/inflections.rb and config/initializers/mime_types.rb and move what was in environment.rb. Split as much as you can in files with descriptive names.

4. Singleton resource, plural controller name

If you were using singleton resource: map.resouce :account, you’ll need to pluralize your controller name. In this case AccountsController. Not sure if it makes more sense, but follows the convention to pluralize controller names I guess…

5. Rename your views

Rails 2.0 brings a beautiful view naming convention:

[name].[content type].[template engine]

eg.: show.html.erb or create.js.rjs

Renaming manually can be pretty painful. Jamie created a Rake task for this.

6. Fix the plugins

Expects some plugins to break. In my case, asset_packager broke, but fixing it was simple: synching method signature for compute_public_path.

I’d recommend checking plugins compatibility before doing the jump. Read the doc. Or if you’re feeling adventurous, give it a try.

7. Add Request Forgery Protection

Cross-site request forgery can be hard to protect from. Not with Rails 2.0.

Add this to your application.rb

# See ActionController::RequestForgeryProtection for details
# If you're using the Cookie Session Store you can leave out the :secret
protect_from_forgery :secret => 'same_as_the_session_one'

And this to your config/environments/test.rb:

# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection    = false

Good luck!

Update: Paolo sent me an article he wrote for upgrading routes to 2.0 w/ a script, nice!

20 Comments

Filed under rails, tips, tutorial

Blitzweekend : Don’t do it!

This post is cross-posted on Blitzweekend’s blog

When Heri asked me to write a post on Blitzweekend’s blog to share some of my tips on building an app in one weekend I thought only of this one:

Don’t do it!

Truth is, if your manager and boss finds out you can do in 2 days what takes us 4 months at work, we’d all be screwed! So keep it quiet and pretend it was an old project you’ve been working on for a long time (months, even years if your boss is not that bright).

See the true story bellow:
Dilbert

If you’re still reading, maybe you don’t care about being labelled as a fast worker. Perhaps you just like creating new things so much, you can help yourself but build stuff again and again! But for most people the problem is: how to turn this into something other people can use. Not only you. Here are 3 tips I’d like to share with you on how to get that damn weekend project out the door, fast, without any pain (until you get labelled a fast worker) while having fun (for now! wait ’till you get labelled!).

1. Focus

Handle FindrKeep everything simple, as simple as it can get. Don’t try to solve all the problems in the world all at once. Find one problem, for example: greasy door handles, and solve that single problem: a web site for locating clean door handles in a specific building.
But hey, it would be cool to also share pictures of the greasy door handle with your friends! That’s when you start loosing focus. Choose only one idea and keep it simple and atomic. It should be impossible to split your project into smaller ones.

2. Remove, don’t add stuff

Here’s a quote I quote way to often:

Perfection is reached not when there’s nothing left to add, but when there’s nothing left to remove
– Antoine de St. Exupery

Don’t think of new features you could add to make it more cool. Think of which one are just too much or don’t add that much to your project. If you need to add features to make your project interesting it’s because your original idea sucks.

3 legs chicken, miam!It’s like a 3 legs chicken, if you pull on the features leg, you’re gonna need more resources and time. But if your time and resources are restricted, your only option is to cut off the features leg (who wants a 3 legs chicken anyway?).

If you think you’re going the wrong direction, start over. That’s why it’s important to put your code under source control from the beginning, revert is your friend when everything goes wrong!

3. Make it work already!

Don’t go big bang approach! Build sometime small, simple (even stupid) and release, rinse and repeat.
Most people don’t take the time to automate parts of their development because they think: it’s just a small project. Bullshit! Because it’s a small project, you’ll be making lots of small changes fast. So you wanna make sure you can deploy in one step, test in one step and restart, stop, cleanup, backup, eat, sleep in one step.

In the case of a web application, deployment can be time consuming if your not used to it. The Internet is full of guides on how to do it. Make sure you deploy a small version before your project gets too much dependencies. If something fails, it will be harder to find out which of the 10 libs you depend on is bogus rather the just making a bare-bone app work. I would also recommend automating your deployment with tools such as Capistrano, Vlad or Paste deployment.

Now that we’re all labelled as fast workers I think blitzweekend should be shrunk to 2 hours.

Have you built an app in 2 days yourself? Share some tips with us! (but don’t tell our bosses)

6 Comments

Filed under montreal, rails, tips

Gravatar caching plugin

Gravatar is slow.

You use Gravatar on your site.

Your site is slow.

We hate slow site.

Caching is fast.

Cache Gravatars on your site.

Your site is fast!

Get it!

script/plugin install http://code.macournoyer.com/svn/plugins/gravatar_cache

Or using piston:

piston import http://code.macournoyer.com/svn/plugins/gravatar_cache vendor/plugins/gravatar_cache

Place something like this in your Rakefile:

def gravatar_emails
  User.find(:all).collect(&:email) # Return the emails you wanna cache
end

Now put everything in place for showtime:

rake gravatar:setup

Cache it!

rake gravatar:cache

You might wanna run this in a cron job, here’s mine:

0 */3 * * * cd /var/www/refactormycode/current && /usr/local/bin/rake gravatar:cache RAILS_ENV=production

Caches it every 3 hours.

Now in your view (or helper):

image_tag Gravatar.new('an@email.com').url

Magic!

Page caching friendly

It should be optimized for really high traffic sites as there’s no hole in the caching process (there’s always a cached version and no chance that someone hits a semi-downloaded file). It is page caching friendly as the url to the image won’t change when it’s cached or not (always /images/gravatars/MD5_OR_YOUR_EMAIL.gif).

Warning

You might have guessed that using a different filename for each Gravatar won’t save you any bandwidth. Even if two images are the same, a different symlink will be created for each, causing a new request for each Gravatar (empty or not). I’d suggest not using this plugin if you’re concerned about bandwidth.

Hope this is helpful to anyone else then me. It was extracted from RefactorMyCode.com. Thanks to Daniel (code) and Matthew Hutchinson (code) for inspiration.

Digg it !

Update: I just found out that Gravatar was bought by Automattic, makers of Worpress. Here’s the news from their blog, TechCrunch, Mashable and Techmeme.

3 Comments

Filed under rails, refactormycode