SlideShare uma empresa Scribd logo
1 de 44
Baixar para ler offline
Coisas que aprendi e
quero passar adiante
Lucas Húngaro
@lucashungaro
GoNow Tecnologia
Lucas
Culinária
Tecnologia
Apple
Home Cinema
Futebol
Café
Drinks
Games MúsicaSoftware
Cinema
Ruby
Duas partes
Serviços e bibliotecas
O que usei e recomendo
Gems e Plugins
bullet
oink
query_reviewer
rails_indexes
kasket
}db performance
& optimization
} caching
} profiling
cachy
Oink
Aug 12 11:31:15 Iron-Man rails[9541]: Memory usage: 101938 | PID: 9541
Aug 12 11:31:15 Iron-Man rails[9541]: Instantiation Breakdown: Total:
39 | User: 20 | FeedItem: 10 | Tag: 9
Cachy
versionamento
evita o “dog pile effect”
caches interdependentes
várias outras features muito interessantes
http://github.com/grosser/cachy
Master/Slave
Para ActiveRecord, DBCharmer
Filas: Resque
Simples, fácil e eficiente
Resque
Resque
monitoramento
plugins
cuidado: json e símbolos
cuidado: tarefas antes seriais passam a ser paralelas
cuidado: locale dos workers (sobem outro contexto)
O Resque adiciona um componente à sua infra-estrutura, mas é feito para ser facilmente
monitorado, estendido e distribuído. Muitas vantagens a um preço muito baixo (e “improvisar” filas
no banco de dados da sua app pode custar bem mais caro)
Arquitetura
Web App == DatabaseView
Utilize filas, caching, server push (Comet, Sockets etc)
Processamento síncrono mínimo
Cloud Computing
Muito cuidado com o hype
Hype não é algo ruim por si só, pois leva a mais inovação mas, sem o devido cuidado, podemos
“errar por empolgação”
Amazon
Noisy neighbors
Latência e I/O
Superpopulação
Caso a caso
Evite o hype
Benchmark
Amazon
Staging/QA/Homologação
Processamento paralelo/distribuído
CDN }The Good
Banco de Dados
I/O intensiva{The Bad
Aumento instantâneo de throughput
Amazon
http://goo.gl/0fgw
Código eficiente
E como padrões ineficientes podem te atrapalhar
Maturidade
O conhecimento, tanto individual, quanto o do grupo, evolui de forma lenta
Excesso de observers/callbacks
Micro-gerenciamento
Ineficiente
Bug prone
Caching
Smart Keys FTW!
aka Versionamento
class User < ActiveRecord::Base
has_many :search_terms, :dependent => :destroy,
:order => "term ASC"
def save_search_term(term)
self.update_attribute(:last_saved_search_at,
Time.now.utc)
search_terms.create(:term => term)
end
def remove_search_term(term_id)
self.update_attribute(:last_saved_search_at,
Time.now.utc)
self.search_terms.destroy(term_id)
end
def saved_search_terms
Rails.cache.fetch(cache_key_for_saved_searches,
:expires_in => 30.days) do
self.search_terms
end
end
private
def cache_key_for_saved_searches
timestamp = self[:last_saved_search_at].to_s.gsub("
","_").gsub(":","-")
"User/#{self[:id]}/search_terms-#{timestamp}"
end
end
cache_proxy
http://github.com/lucashungaro/cache_proxy
Programação defensiva
Não assuma coisas
Principalmente sobre entrada
(robustness principle)
“Be conservative in what you send;
be liberal in what you accept.”
Postel’s Law
Programação defensiva
Gather input
Perform work
Deliver results
Handle errors
Law of Demeter
“Each unit should only talk to its
friends; don't talk to strangers.”
class Company < ActiveRecord::Base
has_many :addresses
def formatted_city
self.addresses.first.city.name
end
end
def formatted_city
main_address.city.name
end
private
def main_address
self.addresses.first
end
SOLID
Jim Weirich
Amanhã, 17h
Single Responsibility
Principle
Uma e apenas uma razão para mudar
Negócios + Persistência
Esconde o domínio
Falta: flexibilidade, isolamento
Fat Models
Camadas Tudo junto e misturado
class ActivityService
def initialize(actor)
@actor = actor
@activities = []
end
def register(type, action, options = {})
raise ActionrgumentError("Every action needs a valid
object") unless options[:object]
(...) # complex treatment of the activity data
end
def process(queue_manager = Resque)
queue_manager.enqueue(ActivityProcessor, @activities,
I18n.locale)
end
(...)
end
SOLID:
SRP: a razão para mudar se torna única - apenas a formatação das opções. Quem cuida da busca é
o wrapper.
OCP: fechada para modificação da implementação, mas aberta para extensão via modificação do
wrapper e injeção da dependência
DIP: duck typing + injeção de dependência - a dependência é gerenciada pelo cliente, liberando o
código e tornando-o mais flexível
class SearchService
def initialize(classes = [])
@classes = classes
end
def add_class(klass)
@classes << klass
end
def execute(query, options = {}, wrapper = ThinkingSphinx)
(...) # options processing (defaults and so on)
wrapper.search(query, options_for_engine)
end
(...)
end
SOLID:
SRP: a razão para mudar se torna única - apenas a formatação das opções. Quem cuida da busca é
o wrapper.
OCP: fechada para modificação da implementação, mas aberta para extensão via modificação do
wrapper e injeção da dependência
DIP: duck typing + injeção de dependência - a dependência é gerenciada pelo cliente, liberando o
código e tornando-o mais flexível
let(:service) { SearchService.new([User]) }
it "should pass default options to the search wrapper" do
default_options = {
:page => 1,
:per_page => 20,
:match_mode => :extended
}
ThinkingSphinx.expects(:search)... # suppressed
service.execute("teste")
end
Sem utilizar a injeção de dependência, acabamos manipulando o comportamento da classe
diretamente, revelando a falta de flexibilidade do código.
let(:service) { SearchService.new([User]) }
it "should pass default options to the search wrapper" do
default_options = {
:page => 1,
:per_page => 20,
:match_mode => :extended
}
wrapper = mock('search_wrapper')
wrapper.expects(:search)... # suppressed
service.execute("teste", {}, wrapper)
end
Com a injeção da dependência, podemos utilizar objetos fake para especificar o comportamento
esperado sem setup adicional, graças ao duck typing.
Também conseguimos o efeito descrito em “Mock roles, not object states” (http://www.infoq.com/
news/2008/08/Mock-Roles-Pryce-and-Freeman)
Conclusões
Guidelines, not laws
Mantra
Se é difícil de testar em
isolamento, está mal projetado*
* 99,99% de chance ;)
Checklists
Uma boa forma de adquirir bons hábitos
ser explícita
ter um nome
ter uma localização clara
Lógica importante deve:
Ao finalizar spec e objeto:
aplica DRY?
tem apenas uma responsabilidade?
depende de componentes que mudam
menos que ele?
Zen of Python
>>> import this
Obrigado
Referências
http://gist.github.com/524462

Mais conteúdo relacionado

Mais procurados

Abstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineAbstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineOtávio Calaça Xavier
 
How to use Elasticsearch Analyzers by EmergiNet
How to use  Elasticsearch Analyzers by EmergiNetHow to use  Elasticsearch Analyzers by EmergiNet
How to use Elasticsearch Analyzers by EmergiNetEmergiNet
 
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeZabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeIgor Nicoli
 
Zabbix Conference LatAm 2016 - Jorge Pretel - Low Level Discovery for ODBC an...
Zabbix Conference LatAm 2016 - Jorge Pretel - Low Level Discovery for ODBC an...Zabbix Conference LatAm 2016 - Jorge Pretel - Low Level Discovery for ODBC an...
Zabbix Conference LatAm 2016 - Jorge Pretel - Low Level Discovery for ODBC an...Zabbix
 
Doctrine 2 camada de persistência para php
Doctrine 2   camada de persistência para phpDoctrine 2   camada de persistência para php
Doctrine 2 camada de persistência para phpFabio B. Silva
 
Grails parte ii - plugins & rest
Grails   parte ii - plugins & restGrails   parte ii - plugins & rest
Grails parte ii - plugins & restJosino Rodrigues
 
Usando seu codigo java no mule part 2
Usando seu codigo java no mule part 2Usando seu codigo java no mule part 2
Usando seu codigo java no mule part 2Jeison Barros
 
ZEO/RelStorage/PostgreSQL
ZEO/RelStorage/PostgreSQLZEO/RelStorage/PostgreSQL
ZEO/RelStorage/PostgreSQLgsroma
 
Fluentd/LogStash + elastic search + kibana
Fluentd/LogStash + elastic search + kibanaFluentd/LogStash + elastic search + kibana
Fluentd/LogStash + elastic search + kibanaCésar Araújo
 
Um Mundo Java Sem XML
Um Mundo Java Sem XMLUm Mundo Java Sem XML
Um Mundo Java Sem XMLiMasters
 

Mais procurados (20)

Ajax
AjaxAjax
Ajax
 
Java 9, 10 e ... 11
Java 9, 10 e ... 11Java 9, 10 e ... 11
Java 9, 10 e ... 11
 
Abstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineAbstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP Doctrine
 
How to use Elasticsearch Analyzers by EmergiNet
How to use  Elasticsearch Analyzers by EmergiNetHow to use  Elasticsearch Analyzers by EmergiNet
How to use Elasticsearch Analyzers by EmergiNet
 
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeZabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
 
Palestra cbq
Palestra cbqPalestra cbq
Palestra cbq
 
Puppet overview
Puppet overviewPuppet overview
Puppet overview
 
Treinamento Elasticsearch - Parte 1
Treinamento Elasticsearch - Parte 1Treinamento Elasticsearch - Parte 1
Treinamento Elasticsearch - Parte 1
 
Zabbix Conference LatAm 2016 - Jorge Pretel - Low Level Discovery for ODBC an...
Zabbix Conference LatAm 2016 - Jorge Pretel - Low Level Discovery for ODBC an...Zabbix Conference LatAm 2016 - Jorge Pretel - Low Level Discovery for ODBC an...
Zabbix Conference LatAm 2016 - Jorge Pretel - Low Level Discovery for ODBC an...
 
Doctrine 2 camada de persistência para php
Doctrine 2   camada de persistência para phpDoctrine 2   camada de persistência para php
Doctrine 2 camada de persistência para php
 
Aula de Node
Aula de NodeAula de Node
Aula de Node
 
Maonamassa Pga
Maonamassa PgaMaonamassa Pga
Maonamassa Pga
 
Java 08
Java 08Java 08
Java 08
 
Implementação de
Implementação de Implementação de
Implementação de
 
Grails parte ii - plugins & rest
Grails   parte ii - plugins & restGrails   parte ii - plugins & rest
Grails parte ii - plugins & rest
 
Usando seu codigo java no mule part 2
Usando seu codigo java no mule part 2Usando seu codigo java no mule part 2
Usando seu codigo java no mule part 2
 
ZEO/RelStorage/PostgreSQL
ZEO/RelStorage/PostgreSQLZEO/RelStorage/PostgreSQL
ZEO/RelStorage/PostgreSQL
 
Fluentd/LogStash + elastic search + kibana
Fluentd/LogStash + elastic search + kibanaFluentd/LogStash + elastic search + kibana
Fluentd/LogStash + elastic search + kibana
 
Node.js: serious business
Node.js: serious businessNode.js: serious business
Node.js: serious business
 
Um Mundo Java Sem XML
Um Mundo Java Sem XMLUm Mundo Java Sem XML
Um Mundo Java Sem XML
 

Semelhante a Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010

Gerenciamento de projetos com o Apache Ant
Gerenciamento de projetos com o Apache AntGerenciamento de projetos com o Apache Ant
Gerenciamento de projetos com o Apache AntDenis L Presciliano
 
Gerenciamento de projetos com o Apache Ant
Gerenciamento de projetos com o Apache AntGerenciamento de projetos com o Apache Ant
Gerenciamento de projetos com o Apache AntDenis L Presciliano
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAThiago Cifani
 
Design Patterns on Rails
Design Patterns on RailsDesign Patterns on Rails
Design Patterns on Railstchandy
 
Tutorial visão automação de testes e casper js
Tutorial visão automação de testes e casper jsTutorial visão automação de testes e casper js
Tutorial visão automação de testes e casper js4ALL Tests
 
Tutorial - Visão sobre Automação de Testes com CasperJS
Tutorial - Visão sobre Automação de Testes com CasperJSTutorial - Visão sobre Automação de Testes com CasperJS
Tutorial - Visão sobre Automação de Testes com CasperJSFrederico Allan
 
SOLID através de BDD: um guia prático para rubistas
SOLID através de BDD: um guia prático para rubistasSOLID através de BDD: um guia prático para rubistas
SOLID através de BDD: um guia prático para rubistaslucashungaro
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpecNando Vieira
 
JavaFX 8, Collections e Lambdas
JavaFX 8, Collections e LambdasJavaFX 8, Collections e Lambdas
JavaFX 8, Collections e LambdasjesuinoPower
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoCezinha Anjos
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidNelson Glauber Leal
 
Oracle e SQL Server na prática mitos, semelhanças e diferenças
Oracle e SQL Server na prática mitos, semelhanças e diferençasOracle e SQL Server na prática mitos, semelhanças e diferenças
Oracle e SQL Server na prática mitos, semelhanças e diferençasLeonardo Pedroso Costa
 
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)Carlos Duarte do Nascimento
 
Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineCampus Party Brasil
 

Semelhante a Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010 (20)

Gerenciamento de projetos com o Apache Ant
Gerenciamento de projetos com o Apache AntGerenciamento de projetos com o Apache Ant
Gerenciamento de projetos com o Apache Ant
 
Gerenciamento de projetos com o Apache Ant
Gerenciamento de projetos com o Apache AntGerenciamento de projetos com o Apache Ant
Gerenciamento de projetos com o Apache Ant
 
Ruby & Rails
Ruby & RailsRuby & Rails
Ruby & Rails
 
Introdução Play framework
Introdução Play frameworkIntrodução Play framework
Introdução Play framework
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVA
 
Design Patterns on Rails
Design Patterns on RailsDesign Patterns on Rails
Design Patterns on Rails
 
Cakephp 2.0 - O que mudou
Cakephp 2.0 - O que mudouCakephp 2.0 - O que mudou
Cakephp 2.0 - O que mudou
 
Tutorial visão automação de testes e casper js
Tutorial visão automação de testes e casper jsTutorial visão automação de testes e casper js
Tutorial visão automação de testes e casper js
 
Tutorial - Visão sobre Automação de Testes com CasperJS
Tutorial - Visão sobre Automação de Testes com CasperJSTutorial - Visão sobre Automação de Testes com CasperJS
Tutorial - Visão sobre Automação de Testes com CasperJS
 
SOLID através de BDD: um guia prático para rubistas
SOLID através de BDD: um guia prático para rubistasSOLID através de BDD: um guia prático para rubistas
SOLID através de BDD: um guia prático para rubistas
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpec
 
JavaFX 8, Collections e Lambdas
JavaFX 8, Collections e LambdasJavaFX 8, Collections e Lambdas
JavaFX 8, Collections e Lambdas
 
Ruby On Rails Regis
Ruby On Rails RegisRuby On Rails Regis
Ruby On Rails Regis
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direito
 
Como fazer boas libs
Como fazer boas libs Como fazer boas libs
Como fazer boas libs
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos Android
 
Oracle e SQL Server na prática mitos, semelhanças e diferenças
Oracle e SQL Server na prática mitos, semelhanças e diferençasOracle e SQL Server na prática mitos, semelhanças e diferenças
Oracle e SQL Server na prática mitos, semelhanças e diferenças
 
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
 
Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App Engine
 
Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3
 

Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010