MountainWest Ruby Conf 2010 Notes

I just finished attending MWRC2010, which I thoroughly enjoyed. The presentations were all excellent. Below are the notes I took during the presentations, really for my own reference…

Day One

Archeopteryx

@gilesgoatboy

Ruby library for making music
uses midi

gem install midilib — for files
gem install midiator — for live midi

google giles midi for github URL; use midi_files branch

foo.bar = lambda { return “bar”}
foo.bar[] #(square brackets can execute — not just .call())

book:
probabilistic reasoning in intelligent systems (judea pearl)

“reason” — the application with synths, drum machines, samplers

probability matrices for determining when different drums sound, to create cool random beats

Cooking with Chef

Recipes for sysadmin tasks
Can auto-restart services on changes to their config files
ERB

Managing Ruby Projects with RVM

command line Ruby Version Manager written in bash

install:
rvm 1.8.6,1.9.1,jruby install

use:
rvm use 1.9.1

gemset:
rvm gemset use rails3
(even different shells can use different gemsets)

tests:
rvm 1.8.6,1.9.1,jruby tests
(runs your tests, logs to log files)

monitoring:
rvm 1.8.6,1.9.1,jruby monitor
(watches your test directory, runs changing tests — like autotest)

benchmark:
rvm 1.8.6,1.9.1,jruby benchmark my_code.rb

raking:
rvm 1.8.6,1.9.1,jruby rake the:rakes

git is recommended for installing rvm
rvm update –head # get this often

use a .rvmrc file
rvm –create –rvmrc use 1.9.1%projecta

rvm info
rvm gemset export projecta.gems
can copy this gem file into another project and do rvm gemset import to use the same gems in another project

#rvm on freenode

Rack

github.com/mjijackson/mwrc2010
mjijackson.com

TODO: Read the spec:
http://rack.rubyforge.org/doc/SPEC.html

an app just needs a call method to run on rack

middleware has an initialize(app) method and a call(env) method

# using ruby
require ‘rubygems’
require ‘rack’
app = Rack::Builder.new {
use Rack::ContentType
use Rack::ContentLength

run lambda {|env| [200, {}, ["Hello world!"]] }
}.to_app
Rack::Handler::WEBrick.run app, :P ort => 9292

# using rackup
# just a few lines in config.ru

# using shotgun
# auto-reloading version of rackup

TODO: see examples on github. check out twitter cache app — makes sure you don’t hit twitter too often

debugging libraries
Rack::Lint
Rack::ShowExceptions
racksh
Rack::Bug

TODO: Check out Rack::Bug

useful middleware
rack/lib — streaming, chunked http responses, etag headers, sessions, cookie handling
rack-contrib
search for “rack” on GitHub

Testing libraries
Rack::MockRequest and Rack::MockResponse
rack-test

Modularity

Yehuda Katz

more in-depth information on blog

“Agile” –
basic plan
build app
requirements
build app
requirements
x n
build app
MODULARITY (figure it out later)

alias_method_chain (starts to fall down in the face of reality)

Reduce Assumptions
so that we can
Increase Reuse
(modularity should only be added in order to increase reuse)

Constants are essentially Global Variables
Rails 2.3: include ActionController::Routing::Routes
Rails 3.0: include application.routes.route_helpers

Rule #1 Eliminate things that are global
Tests are the canary in the coal mine
Be suspicious of any use of Constant.foo, including Constant.new

rails 2.3 — @@perform caching (did not allow changing per request)
rails 3.0 — class_attribute perform caching (now can do controller.perform_caching per request)

Rule #2 Use Objects
Stop worrying about allocations. Object allocation is essentialy free
Don’t hardcode the specific class
Objects present opportunities to memoize
Again, tests are the canary in the coal mine

Rails 2.3 — Template.new — takes a path (hard-coded to file system. hard to store templates in the database).
All the way up the stack takes a path

Rails 3.0 — Entire system is storage agnostic. Template.new takes “Source”, which could be from a database, file, it doesn’t care.

Rule #3 Use Modules (instead of alias_method_chain)
BAD:
class Person
def speak(word)
puts word
end
end

class Yeller
alias_method_chain :speak, :o ld_speak
def speak(word)
old_speak(word.upcase)
end
end

GOOD:
module Speaker
def speak(word)
puts word
end
end

module Yeller
def speak(word)
super word.upcase
end
end

class Person
include Speaker
include Yeller
end

Use ActiveSupport::Concern — mechanism for making sure module includes happen in the right order

How HTTP Solved all your performance problems 10 years ago

Paul Sadauskas

TODO: Read HTTP spec

github.com/paul/mwrc2010

TODO: See last slide with Links — Caching Tutorial, Doing HTTP Caching Right, RFC2616 Section 13

Performance Features in HTTP/1.1
Persistent Connections (Pipelining, Keep-Alive)
built-in to Apache (Keep-alive on) and nginx
Caching
http headers —
Expires and Cache-Control: max-age
(google js libraries are set to a year from now)
(you can also set it in rails)
Validation: Last-Modified, Etag, Vary
Last-Modified — User Agent can use If-Modified-Since to make a request conditional
Etag — If-None-Match
fresh_when(:etag => @sombrero…)
if stale?(:last_modified => @obj.last_modified) #render else return :304 end
Vary Header — keep the cache from server private stuff to the wrong person
Cache-Control public, private
Manipulate: Cache-Control
Hierarchical Proxies
load-balancing proxy (such as haproxy)
caching proxy — provide previous responses without hitting the origin server (squid, varnish)

REST – written by one of the authors of the HTTP spec at the same time he was writing the spec
HATEOAS – Hypertext as the engine of application state (rather than using the session)
Resource – Anything identified by a URI; can have an HTTP verb performed on it; can have multiple representations (HTML, JSON, etc)
Proper Cache treats each resource separately.
POST/PUT/DELETE to a resource invalidates a cached response.
Misusing session makes things uncacheable (for example, flash messages)

if you’re using cookies for auth, need to Vary on the Cookie
if session is in the cookie, the cache is less effective
if page content is generating from session, cache will be invalid

Rails has defaults that support the worst-case behavior.
Tweak defaults when you know you need to be caching

Ruport

Gregory Brown

# No notes for this – it was more of a code walkthrough of how
# you can take a fairly simple concept and make a horribly
# complicated mess out of it :)

Documentation

YARD — documentation tool
Documentation is important
* it makes you actually think about your API

Rule #1 – Consistent
Rule #2 – Correct
* Documentation should be audited/tested just like code
Rule #3 – Coherent
* Documentation should be reviewed just like code

YARD
Consistent
Meta-data @tags
Correct
Roll your own auditing tools — for example github.com/dkubb/yardstick
Coherent
Extensible
gem install yard-rspec — your specs in your docs
gem install yard-sinatra — sinatra routes
gem install yard-pygments — source highlighting for diff langs

gem install yard
host docs at yardoc.org

Code of Art 2 – ruby-processing

github.com/jcasimir

creating images with ruby-processing

beanstalkd — simple, fast task processing
port install beanstalkd
gem install beanstalk-client

Textorize

book – Learning Processing
examples in ruby-processing on github

Lightning Talks

Ship code every single day
– Have Clear Rules
– Lower your Standards
– Get the skill then stop

sequel-mongo, nosql.rb compare to SQLite – sequel-mongo can do all the same thing, gets the same results as sqlite

ci.pivotallabs.com — open sourced on github.com/pivotal/pulse
– ci.rubyonrails.com or something — shows state of ror on different envs
– sad dog pic that the tests don’t pass

memprof.com/demo
– web-based heap visualizer & leak analyzer

sorenson – easy video capture
– squish – captures video, compresses, uploads video
– developer.sorensonmedia.com — free test account
– mtnwest.integrumdemo.com — demo
– mflathers@sorensonmedia.com – email to ask for addl capabilities
– supports flash and mp4 output

HTML5 “Offline” – Reduce Download (for mobile)
– GET request, Accept Application/JSON, respond_with @articles
– update page in js
– text/cache-manifest
– “Local Storage”
– have something that shows up right away, and pull content off local storage

github.com/remi/presentations
– Rack::Payment (on github) — easy ecommerce
– gem rack-paymentd
– “kinda alpha”, but super easy to use
– creates the default payment form and everything for you

managing projects with gnu-screen
– terminal multiplexer
– screen manager
– starts things up for you
– github.com/timcharper/screenmanager

SimpleGeo
– heroku for geo stuff
– restful interface
– geotagged twitter firehose
– stickybits uses it
– austin.vicarious.ly
– open source
– something about openstreetmap in the future

RailsGen
– http://railsgen.com
– RailsBoost++
– more social

ButterflyNet
– www.butterflynet.org
– github – quartzmo
– irb creates tests
– quartzmo@gmail.com
– help requested

CoffeeScript
– compiles down to js
– kind of ruby-like

Google app engine – easy deployment
– sudo gem install google-appengine
– appcfg.rb generate_app mwrc_emo
– cd mwrc_demo
– dev_appserver.rb
– appcfg.rb update .
– now it’s published and running…
– curl command to generate rails app

Day Two

Ruby 124C41+

Matz

from Ralph 124C41+ book — Hugo Gernsback

ruby started in 1993
took 6 months for “hello world”
released publicly Dec 21, 1995 (same age as java)

future -
faster
* multiple vm
* gc improvement
* JIT?
more powerful
* distributed programming
* faster IPC (messagepack)
* multi-core aware
broader
* small -> embedding
* large -> HPC
more modular
* selector namespace – override things only in certain scope, in order to not break other things
* traits – operational combination of features (methods) — module operation +, -
* map etc do not work for infinite enumerable. mapx (assumed name) would return enumerator — lazy list

ruby-core mailing list

From Matz’s screen –
“Not only is the options hash not documented, it is not working either.”

Macros in Ruby

evaluation at parse time

macro add(a,b)
:( ^a + ^b )
end
p add(1,2) => p 1 + 2

“print ‘hello’”
:( print ‘hello’)
proc{ print ‘hello’ }

RedParse
redparse -e ‘a(1)’
redparse -e ‘if a: b end’
redparse -e ‘def of; bar baz end’

slow

Ruby Techniques by Example

Jeremy Evans

1. extending code

class Person
def self.all
end

def name
end
end

hard to override

method lookup – singleton class, methods in class, methods in modules included in class, suerclass

module PersonPlugin
module ClassMethods
end
module InstanceMethods
end
end
use plugin method to extend/include
class Person
plugin PersonPlugin
end

2.
class variables are shared throughout the object hierarchy

3. DSL
ruby 1.9 — BasicObject fix (BasicObject does not have access to constants from Object)
def self.const_missing(name)
::Object.const_get(name)
end

add file and line position to block to trace error

opts.has_key? (instead of logical check)

rescue => e
ensure
blah if e
blahblah
end

Hubris

James Britt

haskell
* purely functional
* type inferencing
* referential transparency – variables don’t vary (like erlang)

this guy’s slides are awesome (illustrator)

immutable data, no state, higher order functions. based on lambda calculus

hubris – ruby – haskell bridge. call haskell code from your ruby code

why? – speed up code, learn haskell, powerful abstractions, parallelism

mandelbrot example – 23 sec in ruby; 3 sec in haskell

TODO: www.lisperati.com/haskell

hubris is on github. repo includes examples.
require ‘hubris’

class Target
hubris :inline => “triple::Int=>Int; triple n = 3*n”
end

t = Target.new
puts t.triple(10)

inline – you don’t have control over visibility of your methods
instead can use external code

GHC 6.12
MRI 1.8.x or 1.9
(see github wiki for instructions on building order)

right now – does not like 64 bit :( (won’t run on snow leopard)
James runs it on a vm

hubris
* grabs haskell
* compiles it into a shared object
* exposes object via ruby shared lib

2 parts: ruby hubris + haskell hubris

quirks:
functions exposed via hubris can only take one argument (they are working on this)
ruby string objects are mapped to haskell bytestrings

Cross-Platform Mobile Applications with Ruby

Sarah Allen
@ultrasaurus

different platforms, different languages as a mobile developer

CDD “Conference Driven Development” github.com/blazingcloud/rhodes_rubyconf

demo of same app on iphone, nexus 1, blackberry

mobile phones have extra features that you should use:
geolocation, camera, connected, everyone you know

mobileruby.heroku.com

rhomobile platform
MVC, but it doesn’t go out to the web — this is all local
request => RhoController -> Rhom -> Local DB

response < -- html erb files <-- render <-- RhoController

rho/rhoapplication

tabs defined in application. each item maps to a controller

MapView - crossplatform rhodes api

phonegap - html + javascript: free. fast-changing. not great with blackberry platform

rhodes - gpl - you have to open source your code. $500 for client-side $5000 for sync server (most applications don't need this)

Person.find -- similar to active resource. if keeping data locally, you don't need the sync server

Mongo DB Rules

document based database, open source, C++
Kyle Banker
@hwaet
mongodb.org
google group — mongodb-user

1. get to know the real mongodb (don’t jump straight to the ORM that hides the details)
TODO: http://try.mongodb.org — play with an instance
or using ruby driver

mongo id – timestamp/machine id/process id/counter
BSON – bsonspec.org — binary format
when we call save:
* add an _id
* serialize to BSON – format the data is stored in
* socket.send()
so we don’t have to wait for the response to get the ID

2. use object id
MongoDB standard

3. use rich documents
one document can contain all your data — “human oriented” — doesn’t require 30 joins to different tables
as a traditional database would

dynamic queries
@orders.find(:user_id => 3)
@orders.create_index(’line_items.sku’) <-- indexing an inner object (line items is an array))
@orders.find({'line_items.sku' => ‘rbi-re2′})

query operators – $ne $in $nin, etc

4. array keys rule, too

simplify tiny relations
link = { :title => ‘Hacker News’, :url => ‘blah’, :tag => {’time water’, ‘blah} }
query all links with certain tag can be indexed

many-to-many

5. Use atomic operators
findAndModify Comman
$inc, $set, $push, $pop

6. map-reduce is for aggregation. results in a new collection
map = <<-MAP
function() {
emit(this['shipping_address']['zip], {total: this.total})
}
MAP
js -- mongo understands js functions

7. indexes are indexes
collections support up to 40 indexes
similar to relational indexes
don’t build too many
build compound indexes

8. GridFS
specification for storing binary data in mongodb
simple api to read in binary file

9. Replicate and backup

10. Performance notes
ruby driver does a lot of work
embedded documents
— db doesn’t do joins
queries should use indexes
keep indexes in RAM

11. auto-shard, to keep it in RAM
wow, data can be automatically sharded.
mongos – lightweight client, redundant config servers, shards of data

12. Two production cases
sourceforge.net – store all their product pages. each page is in a single document.
github.com — backend analytics
harmonyapp.com — originally mysql, switched to mongo. CMS – supports dynamic data needed for a CMS

vs. couch
couchdb — http, mongo – binary protocol over socket
couch – indexes via map-reduce language. mongo – queries ad-hoc, build indexes more like mysql
mongo – supports atomic updates

trivial relationships should be in its own document
can normalize a little bit

everything UTF-8

have an explain for optimization

roadmap
2d geo indexing
sharding beta – 100% automatic failover

your system’s binary interface

joe damato
http://timetobleed.com

only do this stuff in a vm

it’s very easy to leak references in your ruby code
–a lot of memory
–gc scans each object, wasting time
–how to track them down?

ABI – application binary interface
* alignment
* calling conventions
* object file and library formats
* syscalls

evil devices
nm – dump symbol table
objdump – disassemble objects
readelf (linux)
dwarfdump – debugging info
nm /usr/bin/ruby
objdump -D /usr/bin/ruby
readelf -a /usr/binruby
dwarfdump -a /usr/bin/ruby

registers
%rax – results = 64 bits, 1quadword
%eax – lower 32 bits of %rax
%ax – lower 16 of eax
%ah
%al

ELF objects
* headers
* memprof uses libelf extracting info
.text – code lives here

plt – procedure linkage table

ruby calls rb_newobj – to allocate object, add_freelist – deallocate

hook rb_newobj objdump output – find rb_newobj in memory, and override it
only works for ruby build with –disable-shared (no library.so)

require ‘memprof’
Memprof.start
require “stringio”
SringIO.new
Memprof.stats

tells you exactly which file, line number, class the objects are coming from

can track a block
or dump entire heap as JSON

require ‘memprof/middleware’
- watches your rails stuff

memprof.com

memprof gem – free
github.com/ice799/memprof
don’t gem install memprof (out of date)
#memprof on irc.freenode.net

memprof.com – separate — reads the output

someone recommended reading
Programming From the Ground Up

A Tale of Two Codebases

Pat Maddox

in ruby, happiness matters

business case for happy developers
happy developers are more productive
attracts other good programmers

agile, fast development is good
but it’s important to maintain a sustainable pace

demand excellence
– there is always time to refactor
– there is always time to get the tests working
– push back on business requirements to make time
themed releases — focus on one area at a time
– don’t bite off more than you can chew
– it’s draining to try and improve lots of little things at the same time
– pick items in a similar area from backlog
– gives the opportunity to make all the internal changes you need
technical debt is a myth
– the best time to solve a problem is right now, when you know what it is
– technical debt is often used as more of an excuse
– improve things any time you have the chance

don’t lose sight of passion for ruby & code

Recommended Reading:
smalltalk best practice patterns
design patterns
refactoring

EventMachine

scaling non-blocking i/o in ruby

Aman Gupta
github.com/tmm1
@tmm1

slides on timetobleed.com

EventMachine – implementation of the Reactor pattern

heavy production use

* I/O
* mysql query responses
* http responses
* memcache results
most web apps are I/O bound
basic idea – instead of waiting, use that time for other stuff

–scaling I/O heavy applications

event machine takes blocks of code to execute asynchronously
queue.on_push = proc{ use(queue.pop)}

gem install eventmachine
require ‘eventmachine’

EM.run{
puts “reactor started!”
} # this is blocking. nothing else will run until the reactor is stopped

EM.next_tick – queue a proc to be executed on the next iteration of the reactor loop
— splitting up work across multiple patters
— common pattern – “recursive” calls to next_tick
— tickloop
— not used too often

EM::Iterator

by default, EM does not use threads. EM.defer can set up threads

use EM::Timer instead of sleep (b/c sleep would block the reactor)

EM::Callback – specify event handlers

EM::Deferrable (!= EM.defer)
even if event already fired, the block gets automatically executed
your callback always gets called

EM::Queue – returns async queue
pop takes a block
workers pop items off the queue
items can be processed in parallel

EM::Channel – similar to queue, but publish/subscribe model where multiple things can subscribe

EM.system – run external commands without blocking. block receives stdout and exitstatus

EM Handlers – it is recommended to use these

EM::Connection – networking

EM::Protocols — send_object, receive_object — handles marshalling, unmarshalling of objects

can watch files or processes with the reactor

could use an EM enabled webserver — Thin or Rainbows!
async_sinatra for streaming and delayed responses — good for long polling

here’s the code:
http://gist.github.com/329682

Lightning Talks

Testing Queries
– @ginnyhendry
– Never do an unindexed read
– This test will make sure you always have a good index on your query
– gist.github.com/328822 — mongo specific

git instaweb
– git instaweb –httpd webrick
– nice github like interface without needing internet
– already installed on your system!

ruby-fs-stack gem
– tap into the world’s geneology
– FamilySearch
– new.familysearch.org — collaborative family tree
– REST-like Web Service
- ruby gem: http://github.com/jimmyz/ruby-fs-stack
– Family Search Developers Conference in April

RubyMine
– IntelliJ Ruby IDE — about $100
– nice documentation, code completion, etc

Geo Tweeter
– geo-tweeter.heroku.com
– set or fake out the geolocation on tweets
– sinatra-twitter-oauth

Command Event DTO Architecture
– speaker – Alistair Cockburn
– Hexagonal architecture – insulate app from outside world
– the app never knows anything about the external world
– user
– database
– @gregyoung
– Command Event DTO Architecture
– greg put another hexagon around the database, and app and db talk to each other through message queue

Bash Deployment & Server Manager (BDSM)
– Wayne E. Seguin (RVM guy)
– Service Management via Extensions, and Deployments
– modular — any executable file, template system, config, etc
– deploy, rollback, update

Gitty
– Unobtrusively extending Git
– install hooks from common repository & share hooks with team
– example of hook — don’t allow commits with trailing whitespace
– github.com/timcharper/gitty

Agile – Back to the Future
– Agile is developer-geared
– Wall of Confusion
– agileroots.com

Donkey
– Howard Yeh (hayeah)
– Concurrency == Reliability == Scalability
– Learn from Erlang — use message-passing Actors
– based on EventMachine and AMQP

Leave a Reply