32
Wider Than Rails: Lightweight Ruby Solutions Alexey Nayden, EvilMartians.com RubyC 2011 суббота, 5 ноября 11 г.

Wider than rails

Embed Size (px)

Citation preview

Page 1: Wider than rails

Wider Than Rails: Lightweight Ruby

SolutionsAlexey Nayden, EvilMartians.com

RubyC 2011

суббота, 5 ноября 11 г.

Page 2: Wider than rails

Lightweight != Fast

Lightweight ≈ Simple

суббота, 5 ноября 11 г.

Page 3: Wider than rails

Less code=

Easier to maintain=

(often)

Faster

суббота, 5 ноября 11 г.

Page 4: Wider than rails

Motives to travel light

• Production performance

• Complexity overhead

• Learning curve

• More flexibility

• Self-improvement

суббота, 5 ноября 11 г.

Page 5: Wider than rails

Do you always need all of that?

$  lsapp/config/db/doc/Gemfilelib/logpublic/RakefileREADMEscript/spec/test/tmp/vendor/www/Gemfile.lock.rspecconfig.ru

суббота, 5 ноября 11 г.

Page 6: Wider than rails

Do you always need all of that?

$  lsapp/config/db/doc/Gemfilelib/logpublic/RakefileREADMEscript/spec/test/tmp/vendor/www/Gemfile.lock.rspecconfig.ru

суббота, 5 ноября 11 г.

Page 7: Wider than rails

Lightweight plan

• Replace components of your framework

• Inject lightweight tools

• Migrate to a different platform

• Don't forget to be consistent

суббота, 5 ноября 11 г.

Page 8: Wider than rails

ActiveRecord? Sequel!

• http://sequel.rubyforge.org

• Sequel is a gem providing both raw SQL and neat ORM interfaces

• 18 DBMS support out of the box

• 25—50% faster than ActiveRecord

• 100% ActiveModel compliant

суббота, 5 ноября 11 г.

Page 9: Wider than rails

Sequel ORMclass UsersController < ApplicationController before_filter :find_user, :except => [:create] def create @user = User.new(params[:user]) end protected def find_user @user = User[params[:id]] endend

суббота, 5 ноября 11 г.

Page 10: Wider than rails

Sequel Modelclass User < Sequel::Model one_to_many :comments subset(:active){comments_count > 20}

plugin :validation_helpers def validate super validates_presence [:email, :name] validates_unique :email validates_integer :age if new? end

def before_create self.created_at ||= Time.now # however there's a plugin super # for timestamping endend

суббота, 5 ноября 11 г.

Page 11: Wider than rails

Raw SQLDB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", :pattern=>'A%') do |row| puts row[:name]end

DB.run "CREATE TABLE albums (id integer primary key, name varchar(255))"

db(:legacy).fetch(" SELECT (SELECT count(*) FROM activities WHERE ACTION = 'logged_in' AND DATE(created_at) BETWEEN DATE(:start) AND DATE(:end) ) AS login_count, (SELECT count(*) FROM users WHERE (DATE(created_at) BETWEEN DATE(:start) AND DATE(:end)) AND (activated_at IS NOT NULL) ) AS user_count", :start => start_date, :end => end_date)

суббота, 5 ноября 11 г.

Page 12: Wider than rails

Benchmarks

суббота, 5 ноября 11 г.

Page 13: Wider than rails

Clean frontend with Zepto.js

• http://zeptojs.com

• JS framework for with a jQ-compatible syntax and API

• Perfect for rich mobile (esp. iOS) web-apps, but works in any modern browser except IE

• 7.5 Kb at the moment (vs. 31 Kb jQ)

• Officially — beta, but used at mobile version of Groupon ⇒ production-ready

суббота, 5 ноября 11 г.

Page 14: Wider than rails

Good old $$('p>span').html('Hello, RubyC').css('color:red');

Well-known syntax$('p').bind('click', function(){ $('span', this).css('color:red');});

Touch UI? No problem!$('some selector').tap(function(){ ... });$('some selector').doubleTap(function(){ ... });$('some selector').swipeRight(function(){ ... });$('some selector').pinch(function(){ ... });

суббота, 5 ноября 11 г.

Page 15: Wider than rails

Xtra Xtra Small: Rack

• Rack is a specification of a minimal Ruby API that models HTTP

• One might say Rack is a CGI in a Ruby world

• Only connects a webserver with your «app» (actually it can be just a lambda!)

суббота, 5 ноября 11 г.

Page 16: Wider than rails

Rack• You need to have an object with a method

call(env)

• It should return an array with 3 elements[status_code, headers, body]

• So now you can connect it with any webserver that supports Rackrequire ‘thin’Rack::Handler::Thin.run(app, :Port => 4000)

• Lightweight webapp completed

суббота, 5 ноября 11 г.

Page 17: Wider than rails

Rack App Exampleclass ServerLoad def call(env) [200, {"Content-Type" => "text/plain"}, ["uptime | cut -f 11 -d ' '"]] endend

суббота, 5 ноября 11 г.

Page 18: Wider than rails

Metal. Rack on Rails

• ActionController::Metal is a way to get a valid Rack app from a controller

• A bit more comfortable dealing with Rack inside Rails

• You still can include any parts of ActionController stack inside your metal controller

• Great for API`s

суббота, 5 ноября 11 г.

Page 19: Wider than rails

Metallic APIclass ApiController < ActionController::Metal include AbstractController::Callbacks include ActionController::Helpers include Devise::Controllers::Helpers before_filter :require_current_user

def history content_type = "application/json" recipient = User.find(params[:user_id]) messages = Message.between(current_user, recipient)

if params[:start_date] response_body = messages.after(params[:start_date]).to_json else response_body = messages.recent.to_json end endend

суббота, 5 ноября 11 г.

Page 20: Wider than rails

Sinatra• Sinatra should be considered as a compact

framework (however they prefer calling it DSL) replacing ActionController and router

• You still can include ActiveRecord, ActiveSupport or on the other side — include Sinatra app inside Rails app

• But you can also go light with Sequel / DataMapper and plaintext / XML / JSON output

суббота, 5 ноября 11 г.

Page 21: Wider than rails

require 'rubygems'require 'sinatra'

get '/' do haml :indexend

post '/signup' do Spam.deliver(params[:email])end

mime :json, 'application/json'get '/events/recent.json' do content_type :json Event.recent.to_jsonend

Sinatra

суббота, 5 ноября 11 г.

Page 22: Wider than rails

Padrino. DSL evolves to a framework

• http://www.padrinorb.com/

• Based on a Sinatra and brings LIKE-A-BOSS comfort to a Sinatra development process

• Fully supports 6 ORMs, 5 JS libs, 2 rendering engines, 6 test frameworks, 2 stylesheet engines and 2 mocking libs out of the box

• Still remains quick and simple

суббота, 5 ноября 11 г.

Page 23: Wider than rails

Padrino blog

class SampleBlog < Padrino::Application register Padrino::Helpers register Padrino::Mailer register SassInitializer

get "/" do "Hello World!" end

get :about, :map => '/about_us' do render :haml, "%p This is a sample blog" end

end

$ padrino g project sample_blog -t shoulda -e haml \ -c sass -s jquery -d activerecord -b

суббота, 5 ноября 11 г.

Page 24: Wider than rails

Posts controller

SampleBlog.controllers :posts do get :index, :provides => [:html, :rss, :atom] do @posts = Post.all(:order => 'created_at desc') render 'posts/index' end

get :show, :with => :id do @post = Post.find_by_id(params[:id]) render 'posts/show' endend

суббота, 5 ноября 11 г.

Page 25: Wider than rails

A little bit of useless benchmarking

• We take almost plain «Hello World» application and runab  -­‐c  10  -­‐n  1000

• rack  1200  rps

• sinatra  600  rps

• padrino  570  rps

• rails  140  rps

суббота, 5 ноября 11 г.

Page 26: Wider than rails

ToolsThey don't need to be huge and slow

суббота, 5 ноября 11 г.

Page 27: Wider than rails

Pow

• http://pow.cx/

• A 37signals Rack-based webserver for developer needs

• One-line installer, unobtrusive, fast and only serves web-apps, nothing else

• cd  ~/.powln  -­‐s  /path/to/app

суббота, 5 ноября 11 г.

Page 28: Wider than rails

rbenv

• https://github.com/sstephenson/rbenv

• Small, quick, doesn't modify shell commands, UNIX-way

• rbenv  global  1.9.2-­‐p290cd  /path/to/apprbenv  local  jruby-­‐1.6.4

суббота, 5 ноября 11 г.

Page 29: Wider than rails

One more thing...

суббота, 5 ноября 11 г.

Page 30: Wider than rails

Ruby is not a silver bullet

You should always consider different platforms and languages: Erlang, Scala, .NET and even C++

суббота, 5 ноября 11 г.

Page 31: Wider than rails

Ruby is not a silver bullet

You should always consider different platforms and languages: Erlang, Scala, .NET and even C++

Don't miss Timothy Tsvetkov's speech tomorrow

суббота, 5 ноября 11 г.

Page 32: Wider than rails

[email protected]

суббота, 5 ноября 11 г.