Download - NET Architects Day - DNAD 2011
Discutindo Railse Arquiteturas
a apresentação já vai começar ...
Discutindo Railse Arquiteturas
Fabio Akitawww.akitaonrails.com
@akitaonrails
Fabio Akitawww.akitaonrails.com
@akitaonrails
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
<pró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!
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“Long Tail”
</prólogo>
Pequenos(Startups?)
Grandes(Enterprisey?)
Pequenos(Startups?)
Grandes(Enterprisey?)
DDD
Pequenos(Startups?)
Grandes(Enterprisey?)
DDD
“Light”
Pequenos(Startups?)
Grandes(Enterprisey?)
Complexidade Acidental
Ruby on Rails é a melhor forma de desenvolver qualquer aplicação Web.
Todas as outras formas de desenvolver aplicações Web são inferiores a Ruby on Rails.
Ruby on Rails é uma das maneiras competentes de se desenvolver aplicações Web em alguns cenários.
(linguagem)
1994
(framework web)
2004
1.8.71.9.2
1.9.3-dev2.3.113.0.7
3.1-RC1
1.8.71.9.2
1.9.3-dev2.3.113.0.7
3.1-RC1
1.8.71.9.2
1.9.3-dev2.3.113.0.7
3.1-RC1
1.8.71.9.2
1.9.3-dev2.3.113.0.7
3.1-RC1
gem install rails
rails new nome_do_projeto
gem install rails
rails new nome_do_projeto
gem install rails
rails new nome_do_projeto
SIM! Via CLI! :-P
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
~30 mil gems
~15 GB
bundle install
RubyGems Library Assembly (DLL)
Rake MSBuild
Bundler NuGet
> bundle list
Gems included by the bundle: * abstract (1.0.0) * actionmailer (3.0.7) * actionpack (3.0.7) * activemodel (3.0.7) * activerecord (3.0.7) * activeresource (3.0.7) * activesupport (3.0.7) * arel (2.0.9) * builder (2.1.2) * bundler (1.0.13) * erubis (2.6.6) * i18n (0.5.0)
* mail (2.2.19) * mime-types (1.16) * polyglot (0.3.1) * rack (1.2.2) * rack-mount (0.6.14) * rack-test (0.5.7) * rails (3.0.7) * railties (3.0.7) * rake (0.8.7) * sqlite3 (1.3.3) * thor (0.14.6) * treetop (1.4.9) * tzinfo (0.3.27)
> bundle list
Gems included by the bundle: * abstract (1.0.0) * actionmailer (3.0.7) * actionpack (3.0.7) * activemodel (3.0.7) * activerecord (3.0.7) * activeresource (3.0.7) * activesupport (3.0.7) * arel (2.0.9) * builder (2.1.2) * bundler (1.0.13) * erubis (2.6.6) * i18n (0.5.0)
* mail (2.2.19) * mime-types (1.16) * polyglot (0.3.1) * rack (1.2.2) * rack-mount (0.6.14) * rack-test (0.5.7) * rails (3.0.7) * railties (3.0.7) * rake (0.8.7) * sqlite3 (1.3.3) * thor (0.14.6) * treetop (1.4.9) * tzinfo (0.3.27)
> rake -T
rake about rake db:create rake db:drop rake db:fixtures:load rake db:migrate rake db:migrate:status rake db:rollback rake db:schema:dump rake db:schema:load rake db:seed rake db:setup rake db:structure:dump rake db:versionrake doc:app
rake log:clear rake middleware rake notes rake notes:custom rake rails:template rake rails:update rake routes rake secret rake stats rake test rake test:recent rake test:uncommitted rake time:zones:all rake tmp:clear rake tmp:create
> rails generateUsage: rails generate GENERATOR [args] [options]
General options: -h, [--help] # Print generator's options and usage -p, [--pretend] # Run but do not make any changes -f, [--force] # Overwrite files that already exist -s, [--skip] # Skip files that already exist -q, [--quiet] # Suppress status output
Please choose a generator below.
Rails: controller generator helper integration_test mailer migration model
observer performance_test plugin resource scaffold scaffold_controller session_migration stylesheets
> rake middleware
use ActionDispatch::Staticuse Rack::Lockuse ActiveSupport::Cache::Strategy::LocalCacheuse Rack::Runtimeuse Rails::Rack::Loggeruse ActionDispatch::ShowExceptionsuse ActionDispatch::RemoteIpuse Rack::Sendfileuse ActionDispatch::Callbacksuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacheuse ActionDispatch::Cookiesuse ActionDispatch::Session::CookieStoreuse ActionDispatch::Flashuse ActionDispatch::ParamsParseruse Rack::MethodOverrideuse ActionDispatch::Headuse ActionDispatch::BestStandardsSupportrun Demo::Application.routes
Rack Middlewares
Web Server
Rack Middlewares
Routes
Controller
ModelView
Response Request
Web Server
Rack Middlewares
Routes
Controller
ModelView
Response Request
Web Server
Rack Middlewares
Routes
Controller
ModelView
Response Request
Application Server Rack:
Mongrel,Thin,
Passenger,Unicorn
Web Server
Rack Middlewares
Routes
Controller
ModelView
Response Request
Web Server:NginX
Apache
Application Server Rack:
Mongrel,Thin,
Passenger,Unicorn
NginX, Apache, Lighty, IIS
Mongrel, Thin, Unicorn, Passenger
Reverse Proxy
ActiveRecord/DataMapper
RDBMS/NoSQL
NginX, Apache, Lighty, IIS
Mongrel, Thin, Unicorn, Passenger
Reverse Proxy
ActiveRecord/DataMapper
RDBMS/NoSQL
TidyTDS
SQL ServerSQL Azure
NginX, Apache, Lighty, IIS
Mongrel, Thin, Unicorn, Passenger
Reverse Proxy
ActiveRecord/DataMapper
RDBMS/NoSQLWeb Services (REST, SOAP)
ActiveResource/RestClient/Savon
WCF
NginX, Apache, Lighty, IIS
Mongrel, Thin, Unicorn, Passenger
Reverse Proxy
ActiveRecord/DataMapper
RDBMS/NoSQLWeb Services (REST, SOAP)
ActiveResource/RestClient/Savon
HAProxy
NginX, Apache, Lighty, IIS
Mongrel, Thin, Unicorn, Passenger
Reverse Proxy
ActiveRecord/DataMapper
RDBMS/NoSQLWeb Services (REST, SOAP)
ActiveResource/RestClient/Savon
HAProxy
Varnish
NginX, Apache, Lighty, IIS
Mongrel, Thin, Unicorn, Passenger
Reverse Proxy
ActiveRecord/DataMapper
RDBMS/NoSQLWeb Services (REST, SOAP)
ActiveResource/RestClient/Savon
HAProxy
Memcache
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
$(':checkbox').map(function() { return this.id;}).get().join(',');
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
EventMachine
NginX
Request Request Request Request Request Request
RDBMS
EventMachine “Look Ma!
No Threads!”
NginX
Request Request Request Request Request Request
RDBMS
EventMachine “Look Ma!
No Threads!”
5k ~ 10kconexões
NginX
Request Request Request Request Request Request
RDBMS
EventMachine “Look Ma!
No Threads!”
5k ~ 10kconexões
ConexõesLongas
<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.0.5
2007
2008
2009
2010
2011
6Ruby on Rails
2.0.0
2.1.02.0.5
2.1.2
2007
2008
2009
2010
2011
6
3
Ruby on Rails
2.0.0
2.1.0
2.2.0
2.0.5
2.1.2
2.2.3
2007
2008
2009
2010
2011
6
3
4
Ruby on Rails
2.0.0
2.1.0
2.2.0
2.3.0
2.0.5
2.1.2
2.2.3
2.3.11
2007
2008
2009
2010
2011
6
3
4
12
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.11
3.0.7
2007
2008
2009
2010
2011
6
3
4
12
8
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.11
3.0.7
2007
2008
2009
2010
2011
Ruby on Rails
31Versõ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
Rails 3.1:Release Candidate
(may 2011)
RubyConfBrasil
3 e 4 de Novembrowww.rubyconf.com.br
<epílogo>
@pedroh96
Pedro Franceschi
15 anos
@pedroh96
Pedro Franceschi
9 anos
@pedroh96
Pedro Franceschi
6 anos
@pedroh96
Pedro Franceschi
@pedroh96
Pedro Franceschi
</epílogo>
Obrigado!www.akitaonrails.com
.com.br
u.akita.ws/dnad11