Peter Hellberg

Boulderklättrande Rubyutvecklare som gärna jobbar med ramverken Sinatra och jQuery.

Peters hemsida: http://c7.se

RailsConf: Onsdag

Keynote: Chris Wanstrath

Presentationen: https://gist.github.com/0a2655aed6a26fa15a02

Rails Metal, Rack, and Sinatra

Adam Wiggins (Heroku) berättade om hur Rails Metal går att kombinera med Sinatra.

What Makes Ruby Go: An Implementation Primer

Charles Nutter (Sun Microsystems) och Evan Phoenix (Engine Yard) gick igenom olika delar av Ruby som man behöver tänka på för att inte stöta på prestandaproblem.

Metodanrop

Att cache:a metodanrop ger generellt sett den största prestandavinsten.

Object#extend är dock ett stort problem för att kunna cache:a metodanropen.

Det är viktigt att förstå hur extend fungerar så att man inte tömmer
metodanropscachen i onödan.

Konstanter

För att hålla prestandan upp ska man hålla konstanter konstanta, inte helt oväntat.

Options Argument

En option hash strider mot DRY.
Det är mycket snabbare att använda diskreta argument.

obj.run rescue nil

Det är otroligt ovanligt att man vill fånga alla StandardError, vilket är 101 underklasser; IOError, SecurityError, TypeError, Etc.

obj.run rescue Exception

I stort sett samma sak som rescue nil, fast värre, nu kan man inte ens ctrl-C’a ut ur koden.

Autoload

Helt tråd-osäkert, fördröjer laddning av koden.
Använder inte Kernel#require, alltså går det inte att köra autoload från gems.

Super

Man måste ta bort blocket om man inte vill att det ska skickas uppåt:

super(a, &nil)

Super ser bara senaste versionen av argumenten:

def foo(a, b)
  a = 1
  b = 'bar'
  super
end

Slutsats

  • Enkel kod > Komplex kod
  • Det finns inga gratis luncher
  • Tänk igenom två gånger, skriv koden en gång
  • YAGNI

Call into your Ruby code! Writing voice-enabled apps in Ruby with Adhearsion

Jay Phillips (Codemecca LLC) visade hur man kan programmera Ruby för att styra Asterisk genom att använda sig av Adhearsion.

Tyvärr fungerade det inte att använda Ahearsions Sandbox på konferensens wlan,
så jag får ta och testa det lite senare.

Verkar intressant att kunna styra sin applikation genom att ringa till den :)

RailsConf: Tisdag

Keynote: Rails 3 ..and the real secret to high productivity

Presentationen (PDF)

David började med en tillbakablick på de 5 år som gått och vad som sagts om ramverket och hur det kom sig att det skapades så många kloner. Han fortsatte med att berätta om några förändringar i Rails 3.0

  • Ny router
  • Snabbare och bättre Rack-stöd
  • XSS skyddet uppdateras
  • JavaScript blir unobtrusive och ramverksagnostiskt
  • Mer agnostisism; Action ORM, Generatorer
  • Refakturering; Abstract Controllers, ActiveRecord, Callbacks

En välkommen förändring är att output i vyerna kommer att bli escape:ad per default. För att skriva ut råformatet använder man metoden raw.

Unobtrusive JavaScript kommer att implementeras genom att använda HTML 5 attribut:

## Rails 2.x
<%= link_to_remote "Delete", :url => @comment, :method => :delete %> 
<a href="#" onclick="new Ajax.Request('/comments/1', {asynchronous:true, 
evalScripts:true, method:'delete'}); return false;">Destroy</a>
 
## Rails 3.x
<%= link_to "Delete", @comment, :remote => true, :method => :delete %> 
<a href="/comments/1" data-remote="true" data-method="delete">Destroy</a>

Och sen appliceras metoderna med JavaScript:

$(document.body).observe("click", function(event) { 
  var element = event.findElement("a['data-remote']"); 
  if (element) { 
    var method = element.readAttribute("data-method") || "get"; 
    new Ajax.Request(element.readAttribute("href"), { method: 
method }); 
    event.stop(); 
  } 
});

Han visade på hur viktigt hög produktivitet faktiskt är, hur motivation snabbt minskar vid svåra problem.

Relaterade bloggposter

The Gilt Effect: Handling 1000 Shopping Cart Updates per second in Rails

Anställda på Gilt Groupe berättade om hur deras serverarkitektur ser ut, de använder PostgreSQL, 400+ Thin servrar, 2 ZXTM’s (Zeus Extensible Traffic Manager)

Applikationen är skriven i Ruby on Rails.

De måste jobba med sharding för att klara av den höga lasten.

De använder ett internt CMS skrivet i Rails och har två “CDN”-servrar framför som serverar förgenererade sidor. (En server på östkusten och en på västkusten)

Stort antal transaktioner

Dedikerade tjänster för varje transaktion – JRuby + EC2 + SQL + Rails

EC2 (lastbalanserad genom Zeus), expanderbar kapacitet, tid/behovsbaserad ökning av tillgänglig kapacitet.

De arbetar tillsammans med Joyent för hosting.

Hög volym / Delat tillstånd

Unik ehandelsmodell, “flash sale” där alla produkter tar slut på en dag.

Inventariemodellen

Gilt hanterar varje fysiskt objekt individuellt

  • Begränsat antal
  • Går inte att få tag i fler

Varukorgsmodellen

Shoppingfasen:

  • Att lägga till en produkt skapar en reservation
  • Om produkten är tillgänglig får man en 10-minuters reservation
    • Man måste betala in

Betalningsfasen

  • Förfråga om att förlänga reservationen
  • Om reservationen är , förlängs den med 10 minuter
    • Man kan får en prioriterad uppgradering
  • Om reservationen inte är valid och det inte finns några lediga produkter
    • Meddelande till kunden att produkten är slut och att man kan skriva upp sig på en väntelista.

Betalning genomförd

Respektive produkt markeras som såld i databasen

Gilts framtidsstrategi

  • Kärntjänsterna är vy-lösa (MC)
  • Enda gränssnittet är JSON/HTTP
  • Externa tjänster skrivna i Ruby, Java för kritiska operationer internt
  • Internt ramverk kallat Blackbird under utveckling, det hanterar skalbar deployment av tjänter i Ruby.

PWN Your Infrastructure: Behind Call of Duty: World at War

Tyvärr fick jag inte plats inne på föreläsningen UI Fundamentals for Programmers med Ryan Singer från 37Signals så det fick bli mitt andrahandsval om hur Agora Games skalar sin serverarkitektur.

Jason LaPorte (Agora Games) talar om vad de tycker är fel med deployment av Rails. Ett av de största problemen är skalbarhet (Av administratörens tid) och i hans värld översätts detta i hur mycket den dagliga arbetsbördan ökar när antalet servrar ökar.

För att hantera fel jobbar de med virtualisering med hjälp av Terremark och replikation för mjukvaruproblem.

De propagerar /usr/local till alla servrar med NFS, vilket gör att uppdateringar sker hyffsat smärtfritt.

De har ett internt system de kallar Overlord skrivet i Rails, det sköter hantering av konfigurationsfiler som sedan laddas ner av respektive server.

Monit ser till att de konfigurerade tjänsterna startas samt startar om tjänster som gått ner.

RRDTool visualiserar hur de olika tjänsterna mår genom att använda Monits xml-format. (http://server/_status?format=xml)

Centraliserad deployment med ett enkelt shellscript som:

  • Updaterar koden
  • Uppdaterar miljön
  • Startar om servrarna

JavaScript Testing in Rails: Fast, Headless, In-Browser. Pick Any Three.

Larry Karnowski och Jason Rudolph (Relevance, Inc.) visar Blue Ridge, ett ramverk för testdriven utveckling med JavaScript.

Delarna i Blue Ridge

  • Rhino – en Java-baserad JavaScript interpreter
  • Screw.Unit – en BDD syntax för JavaScript, liknar RSpec
  • Smoke – ett JavaScript mocking & stubbing bibliotek, liknar Mocha
  • env.js – en DOM implementation skriven helt i JavaScript

Det verkar grymt användbart att kunna köra tester av alla JavaScript från kommandoraden eller en CI-server. Tyvärr verkar det inte som om env.js fungerar tillsammans med jQuery 1.3.x så de kör med jQuery 1.2.6. De jobbar dock på att lösa problemet.

Relaterade länkar

Smacking Git Around – Advanced Git Tricks

Presentationen (PDF) |
Cheat-sheet (PDF)

Scott Chacon (GitHub) började med “Git in 60 seconds” och gick vidare med att gå igenom mer avancerade funktioner i Git.

  • Med filter branches kan man ta bort en fil från alla commits.
  • Subtree merging är ett alternativ till Submodules.
  • Git Bisect är användbart för att hitta vilken commit som orsakade problem
  • Man kan diffa binära filer genom att använda .gitattributes

Quality Code with Cucumber

Aslak Hellesøy (Bekk Consulting AS) berättar om BDD med hjälp av Cucumber.

  • Step – Method invocation
  • Step definition – Method definition

Jag är inte helt övertygad om att det är en bra idé att kunna definiera dataset i sina steps, men för övrigt verkar det riktigt användbart.

Tags är en riktigt trevlig liten feature.

RailsConf: Tutorials

ruby_dinette

JRuby on Rails – Nick Sieger (SUN Microsystems)

Presentationen: jruby-railsconf-2009.pdf

Huvudpunkterna på föreläsningen var:

  • Installation
  • Utveckling
  • Prestandatestning
  • Interaktion med Java
  • Testning

Jag hade gärna sett att han gått in lite mer på djupet om skillnaderna
mellan JRuby och MRI, Olika sätt att deploya (Han visade GlassFish,
med tveksamt resultat)

Ett verktyg jag helt klart kommer att använda mig av i framtiden är VisualVM.

A Hat Full of Tricks with Sinatra – Blake Mizerany (Heroku)

Det första som händer är att Christian Neukirchen,
huvudutvecklaren av Rack sätter sig brevid mig.

Första fjärdedelen av Blakes föreläsning handlar inte om
Sinatra över huvud taget utan om just Rack.

Minimal Rack-applikation

run lambda { |env| [200, {'Content-Type' => 'text/html'}, ['Hello']] }

Minimal Sinatra-applikation

require 'sinatra'
 
get '/' do
  'Hello'
end

Rekomenderade böcker

Exempelkod

gae_hackathon

Ruby on Rails under Nginx med Phusion Passenger

Nginx

Sedan några timmar så kan man köra Phusion Passenger under Nginx!

Phusion Passenger och Apache har under en tid varit det populäraste sättet att enkelt driftsätta Ruby on Rails och Rack-applikationer. Nu kan man alltså välja att köra Passenger under den ryska (och tokigt snabba) Nginx.

Det enda man behöver göra är:

  1. Installera gem: sudo gem install passenger
  2. Köra Nginx installern: sudo passenger-install-nginx-module
  3. Konfigurera (Det mesta sköts automagiskt)
  4. Starta

Mer ingående instruktioner finns på Phusion’s blogg

Phusion Passenger

Hongli Lai och Ninh Bui presenterade Phusion Passenger (också känd som mod_rails) under RailsConf 2008, det var då jag verkligen fick upp ögonen för projektet.

I den nya versionen har Phusion-grabbarna förutom att man nu kan använda sig av två olika webbservrar för att köra Passenger lagt till:

  • Stöd för ”chunked file uploads”
  • Stöd för Capistranos sätt att sköta driftsättning (Symlänkning av current osv.)
  • Förmåga att ladda application_controller.rb från en icke-standard sökväg
  • ”Worker process event hooks” för Rack

Nginx

Nginx driver ett flertal stora webbplatser, såsom WordPress, Hulu, Github, och Ohloh. Den serverar mer än två miljoner webbplatser och är därmed den näst populäraste webbservern under Linux.

Fördelning mellan olika webbservrar

Sinatra och Google Spreadsheet

Efter att ha sett scriptet follow_iphone_devs.rb fick jag idén att kombinera Sinatra och google-spreadsheet-ruby som ett exempel på vad man kan göra i Ruby om man inte har behov av ett större ramverk som Ruby on Rails.

Sinatra
Sinatra är ett DSL för att snabbt och enkelt skapa webbapplikationer i Ruby:

# myapp.rb
require 'rubygems'
require 'sinatra'
get '/' do
  'Hello world!'
end

Komma igång

Först av allt behöver vi Ruby och RubyGems. Eftersom jag använder OS X så är de redan installerade. (Men se till att du har en uppdaterad version av RubyGems)

Om du inte redan har lagt till GitHub i listan över dina gem sources:

gem sources -a http://gems.github.com

Nu är vi redo att installera de gems vi kommer att använda:

sudo gem install sinatra gimite-google-spreadsheet-ruby haml

Nu är vi redo att börja skriva vårt script:

sinatra-and-google-spreadsheet.rb

Först tar vi och laddar in de gems vi kommer använda (Sinatra kommer att ladda in Haml åt oss):

require 'rubygems'
require 'sinatra'
require 'google_spreadsheet'

Nu tar vi och aktiverar sessioner:

# We want to save the posts in a session variable
set :sessions, true

OBS: Detta är självklart ingen lösning som skalar men det fungerar bra för vårt syfte.

Metoderna för att hämta datat från Google Spreadsheet:

def get_posts
  # Retrieve and return the posts
  session["posts"] ||= retrieve_posts
end
 
def retrieve_posts
  # Empty posts hash
  posts = {}
 
  # Log in to Google Spreadsheet
  session = GoogleSpreadsheet.login('xxxxxxxx', 'xxxxxxxx')
 
  # First worksheet of 
  #  http://spreadsheets.google.com/ccc?key=peGTxx6h1WT0ihw9-QETbQg
  ws = session.spreadsheet_by_key("peGTxx6h1WT0ihw9-QETbQg").worksheets[0]
 
  # Iterate over all the rows in the spreadsheet
  for i in 1...ws.num_rows
    # Store the data Identify data using the slug
    posts[ws[i+1,5]] = {
      :title    => ws[i+1,1],
      :content  => ws[i+1,2],
      :date     => Date.parse(ws[i+1,3]),
      :author   => ws[i+1,4],
    }
  end
 
  # Return the retrieved posts
  posts
end

Vi använder memoization för att det bara ska bli en förfrågning till Google per session

Startsida listar helt enkelt alla poster:

get '/' do
  # Get all the posts
  @posts = get_posts
 
  # Render the index template
  haml :index
end

Respektive post har en ”slug” som används i urlen:

get '/:slug' do
  # Get the post
  @post = get_posts[params[:slug]]
 
  # Render the post template
  haml :post
end

Nu definierar vi de Haml-mallar vi använder på sidorna:

__END__
 
@@ layout
%html
  %head
    %title Sinatra and Google Spreadsheet
  %body
    = yield
 
@@ index
%h1.title All posts
 
- @posts.each do |slug, post|
  %ul
    %li
      %a{:href => slug}
        = post[:title]
@@ post
%h1.title
  = @post[:title]
 
%div
  Published
  %span.date
    = @post[:date]
  by
  %span.author
    = @post[:author]
 
%p.content
  = @post[:content]
 
%a{:href => '/'} << Back

Starta scriptet

$ ruby sinatra-and-google-spreadsheet.rb 
== Sinatra/0.9.1 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.0.0 codename That´s What She Said)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop

Om allt går som det ska så ska vi nu ha en server på http://localhost:4567/.

Resultat

Från ett kalkylblad på Google Spreadsheet:

Data från Google Spreadsheet

Data från Google Spreadsheet

Till en sida serverad med Sinatra:

Post om Ruby

Resultatet

Att man kan åstadkomma så mycket med under 100 rader Rubykod är rätt imponerande, speciellt om man tänker på att vi då även räknar in kommentarer och mallar.