Plugin ActsAsSolrReload para o Rails

Gravei um screencast com o Diego Carrion, que explicou mais detalhes nesse post. Iremos melhorar esse vídeo para aumentar a fonte, mas para não ficarem muito curiosos a gente já está liberando o link.

O Solr é um projeto open source da apache e é baseado no Lucene para engine de busca. O Solr faz buscas via XML/HTTP e API JSon e possui funcionalidades de facets, cache, replicação, uma interface de administração web, etc.

O Diego fez um fork do plugin ActsAsSolr e criou o ActsAsSolrReload, já com uma configuração para fazer buscas de geo-localização e buscas com relevância.

Confiram o screencast nesse link

Anúncios

Rails Rumble 2009

Hoje começa mais um Rails Rumble, uma competição de desenvolvimento Rails em 48 horas com no máximo quatro pessoas. As equipes se organizam em um final de semana para modelar, desenvolver, configurar o servidor e fazer o deploy de uma micro aplicação rails na web. Tudo partindo do zero, ou seja, não pode haver uma linha de código sequer antes do início da competição.

Leiam essa matéria na InfoQ Brasil e o post que o Rafael Rosa publicou no Ruby Inside Brasil.

Publicado em noticia, rumble. Tags: , . 1 Comment »

Por onde ando…

Uma passada rápida no meu blog para tirar as teias de aranha 🙂 O que estou fazendo?

Estive recentemente em dois eventos, Google Developer Day e Encontro Ágile / Mingle Retrospective. O próximo da lista será o evento de Rails organizado pela comunidade de São Paulo, o Guru-SP. Esse será o Quinto Encontro do grupo e ocorrerá nesse sábado, dia 18/07.

Estive trabalhando no meu artigo da Java Magazine que será publicado na edição número 72. O assunto será sobre Domain-Driven Design, altamente recomendado para nossa área, independente de sua Linguagem de Programação de preferência. Essa foi uma experiência muito interessante e de grande aprendizado. Espero que comprem a revista e me dêem feedback!

Atualmente estou trabalhando na Gonow com Rails, Sinatra, e outras coisas mais com Ruby. A empresa está patrocinando equipes para o Rails Rumble 2009, graças aos esforços do Diego Carrion que correu atrás dessa oportunidade. Veja esses dois posts aqui e aqui.

Para terminar, estou aguardando a aprovação de minha palestra no Just Java 2009 e quem sabe um BoF no Rails Summit 2009.

E não se esqueçam de me seguir no Twitter.

Publicado em noticia. 2 Comments »

Entendendo MapReduce

Sabemos que ter um bom modelo de banco de dados relacionais é importante, porém com a necessidade de aplicações mais escaláveis nos dias atuais, talvez você precise “desnormalisar” o seu banco de dados. O que adiantaria uma foreign key se você tem tabelas espalhadas em diversos data sources? Por questões de performance, dados podem ser distribuídos em data centers distintos, então como buscar pelo id se você não sabe onde está esse dado? Por isso é importantíssimo que a aplicação controle essa integridade, com um bom design OO, para não depender de constraints e stored procedures do banco de dados.

MapReduce é um modelo de programação, e framework introduzido pelo Google para suportar computações paralelas em grandes coleções de dados em clusters de computadores. Agora MapReduce é considerado um novo modelo computacional distribuído, inspirado pelas funções map e reduce usadas comumente em programação funcional. MapReduce é um “Data-Oriented” que processa dados em duas frases primárias: Map e Reduce. A filosofia por trás do MapReduce é: Diferentemente de data-stores centrais, como um banco de dados, você não pode assumir que todos os dados residem em um lugar central portanto você não pode executar uma query e esperar obter os resultados em uma operação síncrona. Em vez disso, você precisa executar a query em cada fonte de dados simultaneamente. O processo de mapear a requisição do originador para o data source é chamado de ‘Map’, e o processo de agregação do resultado em um resultado consolidado é chamado de ‘Reduce’.

Hoje existem diversas implementações de MapReduce, como : Hadoop, Disco, Skynet, FileMap e Greenplum. Hadoop é a implementação mais famosa implementada em Java como um projeto open source.

Se você quer contribuir nesse projeto, assista esse screencast.

Apresentação da Linguagem Lua

Renato Maia, mestre e doutor em Informática pela PUC-Rio, compareceu na USP para falar sobre a linguagem de programação Lua. Ela é uma linguagem de características dinâmicas desenvolvida no Brasil e utilizada em todo o mundo em centenas de projetos relevantes.

  • Interpretação de Código


code = loadstring( " print( ’ H e l l o , Wo r l d ! ’ ) " )
code ( ) --> H e l l o , Wo r l d !

  • Tipagem dinâmica


a = 1
print( a+a ) −−> 2
a = " a "
print( a+a ) −−> attempt to perform arithmetic on global ’ a ’

  • Coleta automática de lixo


file = assert( io.open( "file.txt " , " w" ) )
file : write( a )
file : close( )
file = nil --> conteudo de 'file’ vira lixo a ser coletado

  • Reflexão compulacional


function string:trim( )
  return self:match ( " ^%s*( . −) % s * $ " )
end

user name = " admin "
print ( username:trim( ) ) −−> admin

Lua é uma linguagem de extensão extensível. É uma biblioteca ANSI C, ou seja, um subset do C. Foi construída na PUC-Rio entre 1993-2009.

A aplicabilidade de Lua é bastante vasta. Usada no Adobe Photoshop Lightroom, Ginga TV Digital, Firmware de impressoras, Analisador de protocolos, Pós Graduação de Filmes, Servidores Web (RealTimeLogic),  Jogos, etc.

Imagem14

Após a palestra, fizemos o DOJO com a participação especial do Renato Maia.

Para detalhes mais técnicos, você pode conferir os ótimos slides do Renato clicando no link:

apres-lua-RenatoMaia

Outra documentação interessante:

http://www.lua.org/manual/5.1/pt/

Publicado em Dojo, linguagens. 2 Comments »

O Estado da arte da DSL em Ruby

Estive na apresentação de Glenn Vanderburg, no QCon London 2009, que falou sobre o Estado da Arte da DSL em Ruby. A apresentação e os slides você pode conferir aqui no site da infoq.

A idéia de fazer uso de uma DSL interna originou-se aparentemente no Lisp. Em Lisp você não escreve seu programa apenas direcionado na linguagem, você também constrói a linguagem em cima do seu programa:


(task “warn if websites is not alive ”
  every 3 seconds
  starting now
  when ( not (website-alive? “http://example.org”))
  then (notify “admin@example.org”, “server down!”))
)

DSL interna também foi um objetivo de design do Haskell


keepleft (p :>: ps)
  | keepleft p = case partitionFL keepleft ps of
    a :> b -> p:>: a :>: b
  | otherwise = case commuteWhatWeCanFL (p :> ps) of
    a :> p’ :> b -> case partitionFL keepleft a of
      a’ :> b’ -> a’ :> b’ +>+ p’ :>: b

Agora falando em Ruby, uma das principais características da linguagem é a expressividade. O japonês Yukihiro Matsumoto (Matz), criador da linguagem, sempre teve como objetivo fazer o ruby extremamente legível. Para atingir esse objetivo a linguagem tem o recurso conhecido como “Sintax Sugar”. A performance da linguagem não foi o objetivo inicial, e sim a clareza. Por isso o ruby é uma linguagem mais lenta. Entretanto agora com a adoção maior nos projetos de mercado direcionados a web, a preocupação com performance cresceu e o resultado disso foi o recente release da versão 1.9.1 do ruby, com resultados impressionantes de performance.

Deixando a performance de lado e voltando à DSL, em um projeto Rails você pode fazer as seguintes associações em uma classe model:

has_many :favorites, :conditions => {:state => ‘public’}

has_many :roles, :through => :projects, :uniq => true

validates_length_of :login, :within => 3..40, on => :create

validates_presence_of :authority, :if => :in_leadership_role, :message => “must be authorized for leadership”

Fica claro e limpo que o modelo tem uma associação a duas coleções (favorites e roles), e validações ficam explícitas no próprio model. Outro exemplo usado na apresentação citada acima:

#Um intervalo de tempo:

3.years + 13.days + 2.hours

# Quatro meses de agora, na segunda_feira

4.months.from_now.next_week.monday

Muita coisa é possível fazer no ruby por causa do “method_missing” que existe nos objetos. Por exemplo, você pode sobrescrever esse método e incluir um código como esse:


def element(element_name, opts={})
  write “<#{element_name}#{encode_opts(opts)}”
  if block_given?
    puts ”>#{yield}”

  else
    puts “/>”
  end
end

E o resultado disso pode ser fazer uma manipulação simples de html:

xml.html {
  xml.head{
    xml.title(“History”)
  }
  xml.body{
    xml.h1(“Header”)
    xml.p(“paragraph”)
  }
}
Outro exemplo que eu adoro é o uso de Active Record  do Rails. Graças ao “method_missing” podemos fazer uso de métodos que não existem, como por exemplo:

Funcionario.find_by_nome_and_cargo( "Fulano", "Gerente")

E ainda fazer uso de Named Scopes:
Funcionario.gerente.pelo_nome

Na linha acima o Active Record vai trazer todos gerentes ordenados pelo nome.

Ruby é uma linguagem muito boa para escrever DSL internas por ser uma linguagem não-obstrusiva e permite que muitas pontuações sejam opcionais. Porém, DSL não faz o seu software magicamente melhor e devem ser usados com precauções. Nem sempre o código fica mais limpo com esse uso.
Glenn fala sobre a complexidade do software e a indicação do famoso livro de DDD do Eric Evans, e do livro The Mythical Man-Month.

Um bom design de software:
  • Elimine tudo que possível da complexidade acidental
  • Separe o resto

Outras frases muito interessantes dessa apresentação:

  • Linguagens são para pessoas entenderem o domínio
  • Coisas que são implícitas na verdade são complexidades acidentais
  • Aprender a linguagem ajuda a entender o domínio

Um bom design de API:

  • Criar uma DSL para determinada construção é poderoso
  • Você pode refatorar ela quando achar duplicação, complexidade, etc
  • DSL interna é apenas uma parte do bom design da API no Ruby



Publicado em linguagens, QCon, rails. Tags: , . Leave a Comment »

Web Sites de Alta Performance (Frontend)

Sabemos que bancos de dados relacionais costumam ser o gargalo das aplicações web, por isso quando falamos de performance é mais comum focar no processamento do servidor. Já escrevi um post sobre escalabilidade e performance. Porém, muitas vezes não nos preocupamos com o conteúdo que estamos escrevendo nas páginas e as vezes os dados estão prontos para ser exibidos ao usuário mas o browser está se matando para renderizar o conteúdo. Segundo Steve Souders, do Google e autor do livro “High Performance Web Sites“, na maioria das páginas web, o lado do servidor corresponde a menos que 10 a 20 % do tempo de resposta ao usuário. Portanto devemos nos focar nos outro 80 a 90 % de tempo de resposta, que é no lado do cliente (frontend).

Dentre os 80 a 90 % de tempo de resposta, o carregamento do HTML gasta somente 10% da demora. O restante do tempo fica a cargo de Imagens, CSS, Javascript e outros componentes. A maior parte do tempo é gasto fazendo download desses componentes quando ainda não estão cacheados no browser, e ainda tem um tempo para persear  HTML, scripts, e stylesheets.

O livro “High Performance Web Sitesimagem12” fala de 14 regras de performance a considerar ao desenvolver um web site. As regras são:

  • Faça pouco HTTP request
  • Use um CDN
  • Adicione um Expiramento no header
  • Compacte componentes
  • Coloque styles no topo
  • Mova scripts para o final
  • Evite Expressões CSS
  • Faça JS e CSS externos
  • Reduza DNS lookups
  • Minimize JavaScript
  • Evite redirects
  • Remova scripts duplicados
  • Configure ETags
  • Permitir que AJAX faça uso de cache

Configurações

Podem ser feitas configurações  no servidor passando parâmetros no header HTTP para fazer compressão, e manter conexões socket abertas, requisições condicionais e expiramento. Abaixo tem um exemplo de um request e response usando compactação e a mesma conexão para várias requisições (keep-alive)

Request

GET /us.js.yimg.com/lib/common/utils/2/yahoo_2.0.0-b2.js
HTTP/1.1
Host: us.js2.yimg.com
User-Agent:Mozilla/5.0(…)Gecko/20061206Firefox/1.5.0.9
Accept-Encoding: gzip,deflate
Connection: keep-alive

Response

HTTP/1.1 200 OK
Content-Type: application/x-javascript
Last-Modified: Wed, 22 Feb 2006 04:15:54 GMT
Connection: keep-alive

O Gzip reduz em aproximadamente 70% do tempo de resposta, porém evite compactar imagens e PDFs pois a compactação não será tão eficiente. O Apache 1.3 usa o mod_gzip. Já o Apache 2.X usa o mod_deflate. Essa compactação é muito boa, porém faça apenas para conteúdos estáticos, não para dinâmicos como por exemplo o JSP. Abaixo segue uma configuração no apache do mod_deflate para compactar tudo que é js e css.

imagem10

Faça Poucas Requisições HTTP

Cada imagem ou gif é uma requisição diferente ao servidor. Uma técnica interessante é chamada de Estampa CSS. Essa técnica consiste em combinar várias imagens em uma só e controlar a exibição por CSS. Considerando apenas 1 imagem contendo várias outras iamgens, será somente 1 requisição ao servidor.

imagerollover

<div style=”background-image: url(‘a_lot_of_sprites.gif’);

background-position: -260px -90px;

width: 26px; height: 24px;”>

</div>

Outro padrão é a combinação de Scripts e Estilos. Cada arquivo Javascript ou css chamado na página é uma requisição diferente. Combinar os arquivos js em apenas um, faz que haja apenas uma requisição no servidor.
imagem81
9 Requisições !
Porém, juntar tudo em um pode dificultar um pouco a manutenção desses arquivos, por isso existem frameworks que facilitam esse trabalho. No Rails, podemos usar:
<%= javascript_include_tag “prototype”, “cart”, “checkout”, :cache => “shop” %>
E fazer uma única camada usando:
<script type=”text/javascript” src=”/javascript/shop.js”></script>
Os estilos css devem ser chamados no início do arquivo para o browser já saber como renderizar a página. Essa forma não vai diminuir o tempo de carga dos arquivos nem a quantidade de requisições, porém diminui o tempo de resposta do usuário. Já os scripts devem ficar no final do arquivo pois o browser faz várias requisições em paralelo, porém os arquivos js não podem ser baixados simultaneamente. Se houver muitos js no início, o browser espera baixar esses arquivos e somente depois começa a renderizar outros componentes da tela, causando uma sensação de congelamento na página.
imagem11
Na imagem acima o browser começa a carregar simultaneamente um componente css e um componente js, porém o segundo componente js só vai ser carregado depois que o primeiro javascript terminar de carregar.
Faça Javascript e CSS arquivos externos, pois você pode aproveita-los em outras páginas, além de usufruir do recurso de cache do browser. Quando o javascript é carregado ele fica no que chamamos de Primed Cache, e se outra página fazer uso desse javascript ela vai pegar do cache e não do servidor.
AJAX

O AJAX é bastante usado nas páginas web hoje em dia, porém temos que nos preocupar em enviar as mesmas requisições repetidamente ao servidor. Podemos controlar essas requisições com parâmetros para verificar se a informação que estamos solicitando já não foi requisitada antes. Outro exemplo é o autocomplite. É recomendado que o usuário digite pelo menos umas 3 letras para fazer a requisição ajax, porém ele pode continuar digitando mais letras e para cada letra digitada será enviado uma requisição a mais ao servidor. Vai do bom senso alterar essa regra para evitar muitas requisições.
Tabelas
Muita gente gosta de usar tabelas, colocando borda invisível, para organizar os componentes na tela. Porém essa maneira gera elementos no DOM desnecessariamente. Tem um site que mostra uma maneira mais adequada para ter o mesmo efeito sem precisar carregar uma tabela inteira.
imagem7
ETag
Entity Tags (ETags) são um mecanismo que web servers e browsers usam para validar componentes cacheados. O Carlos Brando escreveu dois posts interessantes sobre o assunto, em Rails,  aqui e aqui.
Ferramentas
Existem ferramentas para compactação, como por exemplo: JSMin, ShrinkSafe, Packer, YUI Compressor. Sobre essa última o Paulo Siqueira escreveu um post muito interessante aqui.
Confiram uma palestra de Steve Souders na época que trabalhava no Yahoo.
Screencast
Para quem gostou do assunto tem um screencast muito interessante disponibilizado pela Treina Tom chamado “Otimização de Performance com uso de Padrões Web”
O Renato Elias escreveu um post muito interessante sobre Escalando para alguns milhares, páginas WEB.
Tem outra apresentação interessante aqui.  Apresentação é do pessoal de Stanford, descreve basicamente como medir o tempo de renderização das páginas web pelos browsers e mostra algumas estratégias para diminuir esse tempo.