NET Architects Day - DNAD 2011

Preview:

DESCRIPTION

Palestra sobre Arquitetura, Design e conceitos de pensamento a respeito de desenvolvimento de software e Ruby on Rails.

Citation preview

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>