rs on rails 2011

Post on 15-May-2015

858 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Discutindo Rails e Arquiteturas. Palestra para a RS on Rails 2011

TRANSCRIPT

Discutindo Railse Arquiteturas

a apresentação já vai começar ...

Discutindo Railse Arquiteturas

Fabio Akitawww.akitaonrails.com

@akitaonrails

1 ano atrás 4 pessoas

Hoje 20 pessoas+ USD 1 Milhão/ano

1 ano atrás 4 pessoas

Hoje 20 pessoas+ USD 1 Milhão/ano

1 ano atrás 4 pessoas

Hoje 20 pessoas+ USD 1 Milhão/ano

~1990

Anos 80 Fim Anos 90 Século XXI

Perl

C

Anos 80 Fim Anos 90 Século XXI

Basic

dBase III

Clipper

Pascal

Delphi

ASP

PHP

Python

.NET

Java

ABAP

Ruby

ObjCVB6

1.8.71.9.2

1.9.3-dev2.3.123.0.9

3.1-RC4

1.8.71.9.2

1.9.3-dev2.3.123.0.9

3.1-RC4

1.8.71.9.2

1.9.3-dev2.3.123.0.9

3.1-RC4

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Request

Web Server

Rack Middlewares

Routes

Controller

ModelView

Response Request

Application Server Rack:

Unicorn, Passenger

Web Server

Rack Middlewares

Routes

Controller

ModelView

Response Request

Web Server:

NginXApache

Application Server Rack:

Unicorn, Passenger

Web Server

Rack Middlewares

Routes

Controller

ModelView

Response Request

NginX, Apache

Unicorn, Passenger

Reverse Proxy

ActiveRecord/DataMapper

RDBMS/NoSQL

NginX, Apache

Unicorn, Passenger

Reverse Proxy

ActiveRecord/DataMapper

RDBMS/NoSQLWeb Services (REST, SOAP)

RestClient/Savon

HAProxy

NginX, Apache

Unicorn, Passenger

Reverse Proxy

ActiveRecord/DataMapper

RDBMS/NoSQLWeb Services (REST, SOAP)

RestClient/Savon

HAProxy

Varnish

NginX, Apache

Unicorn, Passenger

Reverse Proxy

ActiveRecord/DataMapper

RDBMS/NoSQLWeb Services (REST, SOAP)

RestClient/Savon

HAProxy

Memcached

Varnish

HTTPD

Request Request Request Request Request Request

RailsApp

RailsApp

RailsApp

RailsApp

RailsApp

RailsApp

RDBMS

HTTPD HTTPD HTTPD HTTPD HTTPD

HTTPD

Request Request Request Request Request Request

RailsApp

RailsApp

RailsApp

RailsApp

RailsApp

RailsApp

RDBMS

HTTPD HTTPD HTTPD HTTPD HTTPD

HTTPD

Request Request Request Request Request Request

RailsApp

RailsApp

RailsApp

RailsApp

RailsApp

RailsApp

RDBMS

HTTPD HTTPD HTTPD HTTPD HTTPD

Mais curto possível!

Thread Context Switch

Thread Context Switch

Request RailsApp

Eventos AssíncronosEnvio de mensagens

HTTPD

Request Request Request Request Request Request

RailsApp

RailsApp

RailsApp

RailsApp

RailsApp

RailsApp

RDBMS

HTTPD HTTPD HTTPD HTTPD HTTPD

NginX

Request Request Request Request Request Request

RDBMS

Async App

NginX

Request Request Request Request Request Request

RDBMS

Async App“Look Ma!

No Threads!”

NginX

Request Request Request Request Request Request

RDBMS

Async App“Look Ma!

No Threads!”

5k ~ 10kconexões

NginX

Request Request Request Request Request Request

RDBMS

Async App“Look Ma!

No Threads!”

5k ~ 10kconexões

ConexõesLongas

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

EventMachine.run do conn = { :host => "0.0.0.0", :port => 8080 } EventMachine::WebSocket.start(conn) do |ws| ws.onopen do puts "WebSocket connection open" # publish message to the client ws.send "Hello Client" end ws.onclose { puts "Connection closed" } ws.onmessage do |msg| puts "Recieved message: #{msg}" ws.send "Pong: #{msg}" end endend

<script src="http://js.pusherapp.com/1.8/pusher.min.js"></script>

<script>var pusher = new Pusher('API_KEY');var myChannel = pusher.subscribe('MEU_CANAL');</script>

<script src="http://js.pusherapp.com/1.8/pusher.min.js"></script>

<script>var pusher = new Pusher('API_KEY');var myChannel = pusher.subscribe('MEU_CANAL');</script>

<script src="http://js.pusherapp.com/1.8/pusher.min.js"></script>

<script>var pusher = new Pusher('API_KEY');var myChannel = pusher.subscribe('MEU_CANAL');</script>

myChannel.bind('coisa-criada', function(thing) { alert('Uma coisa foi criada: ' + thing.name);});

myChannel.bind('coisa-criada', function(thing) { alert('Uma coisa foi criada: ' + thing.name);});

myChannel.bind('coisa-criada', function(thing) { alert('Uma coisa foi criada: ' + thing.name);});

require 'pusher'

Pusher.app_id = 'APP_ID'Pusher.key = 'API_KEY'Pusher.secret = 'SECRET_KEY'

class ThingsController < ApplicationController def create @thing = Thing.new(params[:thing])

if @thing.save Pusher['MEU_CANAL'].trigger('coisa-criada', @thing.attributes) end endend

require 'pusher'

Pusher.app_id = 'APP_ID'Pusher.key = 'API_KEY'Pusher.secret = 'SECRET_KEY'

class ThingsController < ApplicationController def create @thing = Thing.new(params[:thing])

if @thing.save Pusher['MEU_CANAL'].trigger('coisa-criada', @thing.attributes) end endend

require 'pusher'

Pusher.app_id = 'APP_ID'Pusher.key = 'API_KEY'Pusher.secret = 'SECRET_KEY'

class ThingsController < ApplicationController def create @thing = Thing.new(params[:thing])

if @thing.save Pusher['MEU_CANAL'].trigger('coisa-criada', @thing.attributes) end endend

require 'pusher'

Pusher.app_id = 'APP_ID'Pusher.key = 'API_KEY'Pusher.secret = 'SECRET_KEY'

class ThingsController < ApplicationController def create @thing = Thing.new(params[:thing])

if @thing.save Pusher['MEU_CANAL'].trigger('coisa-criada', @thing.attributes) end endend

Arquitetura de Altíssima Concorrência

(

W. Edward Deming

IN GOD WE TRUST

Todos os outros devem trazer dados

EXPERIENCE BY ITSELF BRINGSNOTHING

ACD

P

Ciclo “Plan-Do-Check-Act”(melhoria contínua)

ACD

P

STANDARD

Ciclo “Plan-Do-Check-Act”(melhoria contínua)

ACD

P

Ciclo “Plan-Do-Check-Act”(melhoria contínua)

ACD

P

Ciclo “Plan-Do-Check-Act”(melhoria contínua)

ACD

P

Ciclo “Plan-Do-Check-Act”(melhoria contínua)

ACD

P

Ciclo “Plan-Do-Check-Act”(melhoria contínua)

)

Perl

Python

PHP

Ruby

OMG!

2007

2008

2009

2010

2011

Ruby on Rails

2.0.0

2.1.0

2.2.0

2.3.0

3.0.0

2.0.5

2.1.2

2.2.3

2.3.12

3.0.9

2007

2008

2009

2010

2011

6

3

4

12

10

Ruby on Rails

2.0.0

2.1.0

2.2.0

2.3.0

3.0.0

2.0.5

2.1.2

2.2.3

2.3.12

3.0.9

2007

2008

2009

2010

2011

Ruby on Rails

34Versões!

Web Server

Request

RailsApp

/public/stylesheets

Web Server

Request

RailsApp

ArquivosEstáticos

/public/stylesheets

Variáveis/* CSS */

.content-navigation { border-color: #3bbfce; color: #2b9eab;}

.border { padding: 8px; margin: 8px; border-color: #3bbfce;}

$blue: #3bbfce;$margin: 16px;

.content-navigation { border-color: $blue; color: darken($blue, 9%);}

.border { padding: $margin / 2; margin: $margin / 2; border-color: $blue;}

Nestingtable.hl { margin: 2em 0; td.ln { text-align: right; }}

li { font: { family: serif; weight: bold; size: 1.2em; }}

/* CSS */

table.hl { margin: 2em 0;}table.hl td.ln { text-align: right;}

li { font-family: serif; font-weight: bold; font-size: 1.2em;}

Mixins@mixin table-base { th { text-align: center; font-weight: bold; } td, th {padding: 2px}}

@mixin left($dist) { float: left; margin-left: $dist;}

#data { @include left(10px); @include table-base;}

/* CSS */

#data { float: left; margin-left: 10px;}#data th { text-align: center; font-weight: bold;}#data td, #data th { padding: 2px;}

Selector Inheritance.error { border: 1px #f00; background: #fdd;}.error.intrusion { font-size: 1.3em; font-weight: bold;}

.badError { @extend .error; border-width: 3px;}

/* CSS */

.error, .badError { border: 1px #f00; background: #fdd;}

.error.intrusion,

.badError.intrusion { font-size: 1.3em; font-weight: bold;}

.badError { border-width: 3px;}

class Animal constructor: (@name) ->

move: (meters) -> alert @name + " moved " + meters + "m."

class Snake extends Animal move: -> alert "Slithering..." super 5

class Horse extends Animal move: -> alert "Galloping..." super 45

sam = new Snake "Sammy the Python"tom = new Horse "Tommy the Palomino"

sam.move()tom.move()

class Animal constructor: (@name) ->

move: (meters) -> alert @name + " moved " + meters + "m."

class Snake extends Animal move: -> alert "Slithering..." super 5

class Horse extends Animal move: -> alert "Galloping..." super 45

sam = new Snake "Sammy the Python"tom = new Horse "Tommy the Palomino"

sam.move()tom.move()

var Animal, Horse, Snake, sam, tom;var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child;};Animal = (function() { function Animal(name) { this.name = name; } Animal.prototype.move = function(meters) { return alert(this.name + " moved " + meters + "m."); }; return Animal;})();Snake = (function() { __extends(Snake, Animal); function Snake() { Snake.__super__.constructor.apply(this, arguments); } Snake.prototype.move = function() { alert("Slithering..."); return Snake.__super__.move.call(this, 5); }; return Snake;})();Horse = (function() { __extends(Horse, Animal); function Horse() { Horse.__super__.constructor.apply(this, arguments); } Horse.prototype.move = function() { alert("Galloping..."); return Horse.__super__.move.call(this, 45); }; return Horse;})();sam = new Snake("Sammy the Python");tom = new Horse("Tommy the Palomino");sam.move();tom.move();loadrun

102

Web Server(Produção)

Request

RailsApp

/app/assets

Web Server(Desenvolvimento)

Request

/public

Web Server(Produção)

Request

RailsApp

/app/assets

Web Server(Desenvolvimento)

Request

Sprockets

/public

Web Server(Produção)

Request

RailsApp

/app/assets

Web Server(Desenvolvimento)

Request

Sprockets

Tilt

/public

Web Server(Produção)

Request

RailsApp

/app/assets

Web Server(Desenvolvimento)

Request

Sprockets

Tilt

Ugli!er

/public

ENGINE FILE EXTENSIONS REQUIRED LIBRARIES

ERB .erb, .rhtmlnone

Interpolated String .strnone

Erubis .erb, .rhtml, .erubis erubis

Haml .haml haml

Sass .sasssass

Scss .scsssass

Less CSS .less less

Builder .builder builder

Liquid .liquid liquid

RDiscount

.markdown, .mkd, .md

rdiscount

Redcarpet

.markdown, .mkd, .md

redcarpet

BlueCloth .markdown, .mkd, .md bluecloth

Kramdown

.markdown, .mkd, .md

kramdown

Maruku

.markdown, .mkd, .md

maruku

RedCloth .textile redcloth

RDoc .rdoc rdoc

Radius .radius radius

Markaby .mab markaby

Nokogiri .nokogiri nokogiri

CoffeeScript .coffee coffee-script

Creole (Wiki markup) .creole creole

jQuery Tamanho Tempo

Original Size 621kb

Google Closure 234kb 6.5s

YUI Compressor 240kb 2.7s

UglifyJS 235kb 1.3s

jQuery Tamanho Tempo

Original Size 621kb

Google Closure 234kb 6.5s

YUI Compressor 240kb 2.7s

UglifyJS 235kb 1.3s

jQuery Tamanho Tempo

Original Size 621kb

Google Closure 234kb 6.5s

YUI Compressor 240kb 2.7s

UglifyJS 235kb 1.3s

jQuery Tamanho Tempo

Original Size 621kb

Google Closure 234kb 6.5s

YUI Compressor 240kb 2.7s

UglifyJS 235kb 1.3s

jQuery Tamanho Tempo

Original Size 621kb

Google Closure 234kb 6.5s

YUI Compressor 240kb 2.7s

UglifyJS 235kb 1.3s

Rails 3.1:Release Candidate

(may 2011)

RubyConfBrasil

3 e 4 de Novembrowww.rubyconf.com.br

<epílogo>

Como o cliente explicou

Como o Líder de Projeto entendeu

Como o Analista desenhou

Como o Programador escreveu

Como o Consultor de Negócios descreveu

Como o projeto foi documentado

Como Operações instalou

Como o cliente foi cobrado Como foi o suporte

O que o cliente realmente queria

Requerimentos:ENTENDIDO!

LOL

DESIGN

DESIGN

Pattern PADRÃO

Pattern PADRÃO

Default

STANDARD

“Pattern”

NÃO é “Standard”!

Christopher Alexander

cada padrão (“pattern”)representa nosso melhor chute agora ... os padrões ainda são hipóteses, ... e portanto todos são

tentativas, todos livres para evoluir sob o impacto de novas experiências e

observações."

Christopher Alexander

2 + 2 = 5!

2 + 2 = 5!

2 + 2 = 4!

Bertrand Russel

Bertrand Russel

Aqui estão os fatos. Que conclusões podemos

chegar com eles?

Aqui está a conclusão. Que fatos podemos suportar com eles?

80

20

80

20

80

20

80“Long Tail”

@pedroh96

Pedro Franceschi

15 anos

@pedroh96

Pedro Franceschi

9 anos

@pedroh96

Pedro Franceschi

6 anos

@pedroh96

Pedro Franceschi

@pedroh96

Pedro Franceschi

<epílogo>

Obrigado!

.com.br

www.akitaonrails.com

u.akita.ws/rsonrails11

top related