wider than rails

Post on 17-May-2015

2.431 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Wider Than Rails: Lightweight Ruby

SolutionsAlexey Nayden, EvilMartians.com

RubyC 2011

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

Lightweight != Fast

Lightweight ≈ Simple

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

Less code=

Easier to maintain=

(often)

Faster

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

Motives to travel light

• Production performance

• Complexity overhead

• Learning curve

• More flexibility

• Self-improvement

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

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 г.

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 г.

Lightweight plan

• Replace components of your framework

• Inject lightweight tools

• Migrate to a different platform

• Don't forget to be consistent

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

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 г.

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 г.

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 г.

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 г.

Benchmarks

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

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 г.

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 г.

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 г.

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 г.

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

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

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 г.

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 г.

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 г.

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 г.

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 г.

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 г.

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 г.

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 г.

ToolsThey don't need to be huge and slow

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

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 г.

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 г.

One more thing...

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

Ruby is not a silver bullet

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

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

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 г.

Questions?alexey.nayden@evilmartians.com

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

top related