Posts de ‘Emerson Macedo’

[Emerson Macedo] [NodeJS] Acontecimentos recentes

Monday, August 30th, 2010

Nos últimos meses, tenho me envolvido muito com NodeJS. Estou fazendo vários experimentos, inclusive algumas coisas internas aqui na empresa. Certamente falarei sobre isso mais pra frente.

Por conta desse envolvimento, tenho procurado acompanhar os acontecimentos do mundo NodeJS e vou tentar resumir aqui algumas coisa relevantes dos últimos dias.

Node Knockout

Node Knockout

Apesar de todas as outras coisas importantes que tenho pra falar aqui, nenhuma delas é tão recente e tão interesasnte quanto o evento Node Knockout, que é basicamente uma maratona, onde cada equipe tem 48 horas para desenvolver uma aplicação “do zero”. Esse evento foi totalmente inspirado no Rails Rumble, que já acontece há alguns anos.

Infelizmente não pude participar do evento, pois eu tinha alguns compromissos pessoais, não menos importantes, e que não poderiam ser adiados. Eu ia fazer uma aplicação com um amigo de portugal, o José Moreira. Ele acabou fazendo sozinho e ficou ótimo da minha opinião. Votem nessa app :)

Node Smart Machines

Durante o Node Knockout, a Joyent disponibilizou uma hospedagem chamada Node Smartmachines, com deployment via GIT. É bem parecido com o esquema do Heroku, só que ainda está começando. Pra usar basta criar uma conta aqui e começar a fazer seus testes.

Smart Platform Management

Node 0.2.0

No último dia 20 de agosto, foi lançado a versão 0.2.0 do NodeJS, que basicamente se resume ao upgrade da versão do V8 para 2.3.8, algumas melhorias e correções de bugs. Apesar de ainda estar nessa versão “rasa”, o NodeJS tem evoluido de maneira bem interesante, tentando atacar os pontos mais críticos. Ryan Dahl tem se mostrado bem participativo e acessível na lista de discussão oficial e isso de fato ajuda bastante. A API ainda não pode ser considerada estável, mas já caminha pra isso, conforme o anúncio feito na lista.

Node Package Management Website

O gerênciador de pacotes mais famoso para NodeJS agora tem um site para browsear os pacotes existentes, assim como o famoso RubyGems, o que faz com que ele se distancie mais ainda dos concorrentes, se consolidando mais ainda como a principal opção nesse segmento.

npm (node package manager)

Essas são algumas das novidades do mundo NodeJS. Aguardemos as próximas.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Emerson Macedo] NodeJS no Dev In Sampa

Monday, August 23rd, 2010

Acabei de disponibilizar os slides da minha palestra sobre NodeJS no DevInSampa. A partir de hoje vou começar a blogar meus estudos sobre essa tecnologia e experiências que estou fazendo. Os assuntos abordados serão diversos, dentre eles performance, testes, deployment, desenvolvimento web, aplicações puro TCP e console.

Um obrigado especial a galera do devinsampa (Celestino Gomes, Luis Cipriani e Éverton Ribeiro) e  que organizou muito bem o evento.

Nodejs – A performance que eu sempre quis ter

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Emerson Macedo] RVM com Passenger e múltiplas instâncias HTTPD

Monday, July 19th, 2010

No artigo anterior, falei sobre sobre RVM (Ruby Version Manager), explicando sobre instalação, configuração e seu funcionamento interno. Porém, não mencionei nada sobre seu uso com o Phusion Passenger (A.K.A mod_rails, mod_rack), e algumas pessoas me perguntaram sobre isso. Eu não abordei essa parte no artigo anterior por duas razões: A primeira é porque já era madrugada e o sono já me dominava :) e a segunda porque o artigo iria ficar muito grande e o conteúdo inicial já era suficiente para montar um ambiente local na máquina do desenvolvedor.

Esse artigo basea-se no uso do Apache 2.x e no Sistema Operacional OSX. Porém, as configurações em SOs POSIX se assemelham, portanto usuários do Ubuntu e afins não deverão ter nenhum problema.

Instalando o Passenger em uma Rubie/Gemset

Se você já usa RVM ou seguiu os passos do artigo anterior, já deve ter tudo instalado e configurado e já possui uma Rubie com ou sem Gemsets (não faz diferença ter Gemsets para esse artigo). Caso contrário, leia novamente.

Abra o terminal e entre na sua Rubie/Gemset, instale a gem do passenger e o módulo do apache (ou nginx):

$ rvm use rubie@gemset #ex: rvm use 1.8.7@minhaapp
$ gem install passenger
$ rvmsudo passenger-install-apache2-module

Muita atenção nesse momento. A instalação do módulo do apache (ou nginx) deve ser feita usando rvmsudo. Sem isso não funcionou comigo e acho que com ninguém vai funcionar :)

Feito isso, no fim da instalação do módulo ele vai mandar você colocar aquelas 3 linhas de configuração do Passenger nas suas configs do apache. Eu sugiro criar um arquivo passenger.conf ou similar e colar esse código dentro desse arquivo, pra não misturar com as configs básicas do Servidor Http. Se você estiver usando Mac, as configurações do apache provavelmente estarão em /etc/apache2 e existe um diretório other, onde colocamos as configurações adicionais, como esta que acabamos de criar para o passenger.

Agora precisamos ajustar um detalhe nessas configurações do Passenger. Quando instalamos o Passenger e módulo do apache em uma RVM, a terceira linha da configuração (PassengerRuby) que a instalação sugere, não aponta para o diretório correto, e não funciona. É necessário fazer uma modificação e vou explicar.

Quando instalamos a RMV, ele cria um diretório chamado ~/.rvm/bin, onde ficam todos os executáveis das rubies (ruby, irb, gem, ri, rdoc). A instalação do Passenger não entende isso e aponta para uma estrutura diferente, formada da seguinte maneira: ~/.rvm/rubies/{Rubie}/bin/ruby, e isso não funciona. Portanto, precisamos alterar essa linha para que fique da segunte forma:

$ PassengerRuby ~/.rvm/bin/{Rubie}@{Gemset}

A documentação sugere uma forma diferente dessa, nos indicando executar rvm {Rubie@Gemset} –passenger e substituir essa terceira linha da segunte forma:

$ PassengerRuby ~/.rvm/bin/passenger_ruby

O que isso faz é criar um link symbólico de passenger_ruby apontando para o {Rubie}@{Gemset} que você quer. Eu acho isso desnecessário, principalmente porque você pode querer usar o passenger com várias Rubies diferentes, que é o que vou abordar mais adiante. Portanto, eu prefiro ficar com a primeira opção.

Agora basta configurar o VirtualHost (presumo que você já sabiba fazer isso) e reiniciar o Apache. Nesse momento tudo já deve estar funcionando corretamente e você deve estar conseguindo ver sua aplicação funcionando. Não se esqueça de configurar o /etc/hosts (é bastante comum ver gente capotando porque esqueceu essa parte, rs).

Múltiplas apps em Rubies diferentes

Segundo a documentação do Passenger, a diretiva PassengerRuby deve ser usada apenas uma vez, nos limitando a ter nossas aplicações em uma Rubie/Gemset única. Uma maneira comum de trabalhar com essa limitação é instalar o Ruby Enterprise Edition (i.e. Ruby EE) ou qualquer versão de Ruby e instalar todas as gems de todos os projetos nessa Rubie. A partir daí, basta criar um VirtualHost para cada Aplicação. Essa era a forma que trabalhavamos sem RVM. Com RVM a idéia e sair dessa limitação, podendo por exemplo rodar uma app usando Ruby 1.8.7 com Rails 2.3 e outra com Ruby 1.9.2 e Rails3. Isso inclusive num ambiente de produção, isolando bem as apps e evitando conflitos. Vamos portanto resolver o problema de outra maneira.

Criando uma nova configuração para o Apache

Talvez você não saiba, mas o diretório /etc/apache2 não é o servidor Apache HTTPD propriamente dito, mas as configurações que esse servidor usa quando você sobe a instância. Por padrão, o apachectl procura as configurações nesse diretório, mas é perfeitamente possível indicar o path do arquivo de configuração que você quer usar, e é baseado nisto que vamos usar uma alternativa melhor.

Antes de qualquer coisa, vamos trocar alguns parâmetros na configuração default do Apache, para podermos rodar mais de uma instância sem nenhum tipo de problema acidental. Por padrão, nas configurações em /etc/apache2/httpd.conf tem um Listen definito para *:80. Vamos mudar isso:

Listen 127.0.0.1:80

Mudemos também quaisquer configurações de VirtualHost existentes que estejam usando *:80:

VirtualHost 127.0.0.1:80

Agora chegou a hora de clonar essas configurações para uma nova. Esse trabalho é um pouco chato, portanto resolvi criar um Shell Script para isso chamado osx-clone-apache.sh que pode ser baixado aqui e está no meu gist. Já testei no Snow Leopard e Leopard. Se alguém quiser fazer um para ubuntu e outros SOs é bem vindo e eu coloco como update no artigo.

Baixe o Script e execute a seguinte linha no terminal:

$ sudo ./osx-clone-apache.sh http-clone 127.0.0.1:80 127.0.0.2:80

Onde http-clone é o nome da nova configuração que será criada dentro de /etc, 127.0.0.1:80 é o Listen que está configurado em /etc/apache2 e 127.0.0.2:80 é o novo Listen. Essa nova configuração não leva nada do diretório other nem do passenger_pane_vhosts se você estiver usando o Passenger Preference Pane.

Agora que temos uma nova config do apache apontando para 127.0.0.2:80 precisamos configurar nossa interface de rede para passar a responder a esse ip:

$ ifconfig lo0 alias 127.0.0.2/32

Se não me engano, no Ubuntu isso não é necessário, mas no Mac eu não conheço outra forma de fazer isso. Se alguém souber é bem vindo.

Nesse ponto basta repetir os mesmos procedimentos de configuração de Passenger para novas Rubies e Gemsets para essa nova configuração do apache que acabamos de criar. Mais uma vez não esqueça de ajustar suas configurações no /etc/hosts.

O último passo é subir uma instância do apache usando as novas configurações criadas.

$ sudo apachectl -f /etc/{novaconfig}/httpd.conf -k start

Pronto, você já tem 2 instâncias do Apache rodando versões de Ruby/Rails diferentes na mesma máquina.

Conclusão

O RVM (Ruby Version Manager) trouxe uma nova perspectiva no gerênciamento de ambientes Ruby/Rails. O Deploy de Aplicações com versões de Ruby e Rails usando Phusion Passenger numa mesma máquina se torna trivial, desde que se saiba o que está fazendo. As configurações apresentadas neste artigo podem (e acho que devem) ser usadas também em ambiente de produção, pois a SANDBOX criada é muito mais simples de ser gerênciada do que aquela mistura habitual de VirtualHosts, Gems e afins.

Mãos a obra !!!

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Emerson Macedo] Gerencie seu ambiente Ruby com RVM

Friday, July 16th, 2010

Introdução

Ruby 1.8, Ruby 1.9, Rails 2, Rails 3, cada projeto usando diversas gems. Como isolar esses ambientes para evitar conflitos?

Em Outubro de 2007, surgiu uma ferramenta chamada RVM, com o objetivo de criar ambientes isolados para desenvolver software em Ruby, permitindo que programadores pudessem usar várias versões de Ruby e Gems numa mesma máquina de forma limpa e sem conflitos. O projeto vem se tornando mais popular este ano, e de fato tem se mostrado muito útil. A lista dos autores pode ser conferida aqui.

Instalação

Para instalar o RVM, não é preciso muita coisa além de um ambiente POSIX (linux, bsd, etc). Eu instalei no meu Mac sem problemas. Eu acho que a única coisa que não vem por padrão que você precisa instalar é o git, que é usado para instalar/atualizar o RVM e instalar/atualizar as versões de Ruby.

Dito isso, abra o terminal e execute o seguinte comando:

$ bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

O procedimento não deve demorar mais que alguns minutos, dependendo da sua conexão. Em seguida, abra seu profile (.bash_profile, .profile, .bashrc, etc) e adicione as seguintes linhas:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source “$HOME/.rvm/scripts/rvm”
PS1=”\$(~/.rvm/bin/rvm-prompt) $PS1″

A segunda linha é para que a versão do Ruby que você estiver usando apareça no prompt, caso contrário você vai precisar ficar verificando a todo momento qual versão você está usando e isso pode ser bem chato.

Em seguida, carregue o rvm (da próxima vez que abrir o shell isso não será mais necessário):

$ source ~/.rvm/scripts/rvm

Pronto, o RVM está instalado e é hora de começar a arrumar nosso ambiente.

Instalando versões de Ruby

A partir do RVM, é possível instalar qualquer implementação Ruby. Por exemplo, podemos instalar o Ruby, Ruby Enterprise e o Jruby. Para uma lista completa acesse aqui.

Nesse tutorial, vamos instalar o ruby 1.8.7 . Execute o comando abaixo no terminal:

$ rvm install 1.8.7

1.8.7 é um atalho para o último patchlevel da verão 1.8.7 do Ruby. Em geral, isso funciona para todas as versões. A instalação demora um pouquinho, mas nada absurdo, portanto vá tomar um café e volte. Após o termino, “entre” no ambiente do Ruby instalado.

$ rvm –default 1.8.7

Nesse momento, você entrou no Ruby 1.8.7 e definiu essa VM como default no RVM.

Para voltar ao Ruby do systema (fora da RVM), basta ir no shell e digital:

$ rvm use system

Para listar as VMs instaladas (ou Rubies como preferem os criadores e como chamaresmo a partir de agora), basta digitar:

$ rvm list

Escolha a Rubie e use-a conforme o exemplo abaixo:

$ rvm use 1.8.7

Instalando as Gems

Uma das manias que a maioria dos Rubistas tem é instalar as gems usando sudo. Isso hoje em dia é considerado má prática. Ainda mais com RVM, já que a intenção é criar uma espécie de SANDBOX por usuário/aplicação, conforme veremos a seguir.

Primeiramente vamos ver as gems que estão instaladas na nova Rubie. O comando é o já conhecido gem list. Ao rodar esse comando na Rubie instalada pelo RVM, você pode ter a impressão que suas gems sumiram, mas na verdade isso é exatamente o esperado, pois cada Rubie tem seu ambiente totalmente isolado. Para ter uma idéia, rode o seguinte comando e veja o output:

$ rvm info

O output fornece toda a informação sobre o ambiente dessa Rubie que está sendo usada no momento. Observe bem a linha home: \n gem:. Nela você verá onde estão sendo instaladas as gems. Repare que ele cria uma estrutura de diretórios sugestiva para você manter suas gems bem isoladas. A estrutura é a seguinte:

~/.rvm/gems/{Rubie@Gemset}/

Todas as gems serão instaladas nesse diretório. Não estranhe o @Gemset, falaremos dele adiante.

Vamos então instalar o Rails nessa Rubie. Não use sudo pelo amor de Deus :)

$ gem install Rails –no-ri –no-rdoc

Depois execute um gem list para ver seu ambiente instalado. Se quiser, execute rvm system e veja que suas gems no ruby do sistema provavelmente são totalmente diferentes.

Gemsets

Vamos falar agora do tal @Gemset que eu coloquei na estrutura. Gemsets é uma forma de criar uma SANDBOX mais “profunda”. Em um primeiro momento pode parecer desnecessário, mas se você pensar que pode ter mais de um projeto por Rubie e não quer que as gems deles se misturem nem gerem algum tipo de conflito, essa estrutura passa a fazer todo sentido.

Supunha que você tenha um projeto chamado blog. Para criar uma gemset (e entrar nele) para esse projeto basta executar o seguinte comando:

$ rvm gemset create blog && rvm gemset use blog

Feito isso você verá que no seu prompt (se você fez essa configuração de instalação) estará aparecendo da seguinte forma: rubie@gemset. Rode o comando gemlist e verá que novamente suas gems que foram instaladas na Rubie sumiram. Mais uma vez isso é esperado, pois acabamos de criar uma nova SANDBOX para esse projeto específico. Nesse momento, basta instalar suas gems nessa gemset que seu projeto terá um ambiente totalmente isolado.

Se você executar o rvm info, verá que a home das suas gems está com um path diferente do anterior, pois o rvm criou um diretório para a Ruby com a nova Gemset, deixando tudo muito bem organizado.

Existem algumas gems que todos os projetos podem precisar, como Rake e Capistrano. Não seria uma boa idéia instalar essas gems em cada gemset. O RVM nos dá uma ajuda nesse sentido, criando uma gemset global, permitindo compartilhar gems entre todas as gemsets de uma Rubie. Para instalar uma gem nessa gemset basta mudar para ela e installar, como já vimos anteriormente. Vamos a um exemplo:

$ rvm gemset use global
$ gem install capistrano capistrano-ext –no-ri –no-rdoc

Pronto, essas gems não precisam mais ser instaladas para cada projeto novo que você for rodar nessa Rubie.

Conclusão

O Ruby Version Manager é uma ferramenta muito interessante para gerênciar seu ambiente Ruby. Ter vários Rubies instalado se torna cada vez mais comum, pois os projetos antigos precisam ser mantidos e novos projetos surgem, usando Rubies mais novos. O uso dos gemsets para isolar as gems também faz toda a diferença, evitando diversas dores de cabeça e deixando o ambiente organizado e limpo. Vale a pena experimentar.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Emerson Macedo] Computação Ubíqua e Dispositivos móveis

Tuesday, July 13th, 2010

Introdução

É fato que nos dias de hoje muitas tecnologias novas surgiram no cenário mundial. Temos sido inundados por celulares, smartphones, notebooks, netbooks e outros mais. Hoje em dia existe internet 3G nas principais grandes cidades do mundo. Internet WIFI já é algo comum faz tempo. Esses recursos estão começando a mudar nossas vidas de uma forma surpreendente. Mas será que essa idéia é nova? Quando será que começaram as pesquisas sobre essas tecnologias? Qual será o impacto futuro em nossas vidas? Acredito que estamos realmente num caminho onde a computação fará parte de quase todos os objetos que usamos no dia a dia.

Definição

Ubíquo não é uma palavra muito usada em nosso cotidiano. Portanto, vale a pena apresentarmos alguns significados para nos ajudar a aprofundar mais no assunto.

Ubíquo significa algo universal, ou seja, algo que todos entendem, conhecem. Ubíquo também pode ser interpretado como aquilo que esta presente em todos os lugares, ao mesmo tempo. É como onipresença. Essa segunda definição tem mais a ver com o conteúdo desse artigo.

História

Em 1991, Mark Weiser escreveu um artigo chamado “O Computador do Século 21 (The Computer for the 21st Century). Weiser era cientista chefe do Centro de Pesquisa Xerox PARC. Nesse artigo, ele definiu o termo Computação Ubíqua, que define um contexto onde a presença computacional em algum objeto é totalmente transparente para quem usa e em alguns cenários totalmente invisível. Weiser também exemplifica a escrita, que foi provavelmente a primeira tecnologia de informação e que se tornou Ubíqua em países industrializados. Ele usa esse exemplo para definir que as tecnologias que são mais profundas são as aquelas que “desaparecem”. Por desaparecer, acho que Weiser quis dizer que a tecnologia fica tão arraigada no nosso dia a dia tornando seu uso automático, deixando de ser aquele algo novo e surpreendente. Vislumbrando como seria a computação do nosso século, Weiser também fala sobre redes gigabits, armazenamento de terabytes e sobre Tabs e Pads, que seriam os palms, smartphones, Kindles e iPads que temos hoje. Quase no fim do artigo, ele conta uma estória ilustrativa de uma pessoa vivendo nesse mundo todo conectado e apresenta diversos protótipos feitos por ele e sua equipe de alguns desses equipamentos e tecnologias.

No que diz respeito a tecnologias, lembro-me bem que Java era uma dessas que originalmente foi criada para ser usada em dispositivos embarcados, especialmente na informatização da casa, mas era algo muito avançado para época. Isso surgiu no mesmo ano em que Weiser escreveu seu artigo. No fim das contas a linguagem Java tomou outro rumo, muito bem sucedido por sinal.

Contexto atual e futuro

É impossível negar que a computação Ubíqua tem afetado nosso dia a dia. Hoje temos Hotspots WIFI em diversos lugares. A internet 3G está presente nos celulares modernos, possibilitando infinitas formas de comunicação. Serviços de Voz sobre IP tornaram possível usarmos ferramentas como Skype, que permite obter um número de um País e utilizar em qualquer lugar do mundo. Cada vez mais fazem parte do nosso dia a dia tecnologias como as de automóveis com computador de bordo, iPhones, iPads, totem para compra de ingressos no cinema, totem para check-in de voos, e outros mais.

Outra tecnologia que está acelerando o processo da computação Ubíqua é o Cloud Computing. Há alguns anos, milhares de pessoas tem suas contas de email online em serviços como gmail, yahoo mail e similares, de forma a não precisarem mais de um cliente de email como ferramenta obrigatória em seus computadores. Essa modalidade é conhecida como SaaS (Software as a Service). Outra modalidade é o IaaS (Infrastructure as a Service), onde existe uma infraestrutura transparente para quem contrata servidores, podendo adicionar mais recursos computacionais ao invés de mais um computador ou hardware físico. Mais recentemente surgiram também plataformas para desenvolvimento de software totalmente na web como o Google App Engine, Heroku e outros. Esse é o modelo PaaS (Platform as a Service).

Hoje em dia fala-se muito também em casas inteligentes, um conceito onde toda a casa está interligada e conectada, permitindo que luzes acendam com comando de voz, geladeiras enviem pedidos de compras ao supermercado quando estiverem perto de esvaziar, cafeteiras saberem o horário do seu café da manhã e prepararem o café sem você precisar fazer nada, e por ai vai. Esse conceito está ligado a Computação Pervasiva, que é uma espécie de subárea da Computação Ubíqua. Quem assistiu o filme “O Demolidor” (1993), com os atores Silvestre Stalone e Welsey Snipes, lembra que esses conceitos estão presentes no filme. Embora atualmente existam algumas iniciativas de empresas nesse ramo de Computação Pervasiva, essa tecnologia ainda está bem distante de uma adoção em massa.

Falando de futuro, é bem verdade que ainda não chegamos no nível onde Weiser aponta em seu artigo, mas afinal, ainda estamos no início do século, tendo passado apenas uma década. Uma das frases ditas por ele nesse artigo que chamou muito a atenção sobre esse futuro foi: “Não precisamos de nenhuma revolução na inteligência artificial, apenas incorporar a computação no cotidiano”.

Conclusão

O Caminho para Computação Ubíqua tem avançado muito nos últimos anos. As pesquisas e previsões de Mark Weiser tem se concretizado, quase que como uma profecia. Como profissionais de TI, nos resta estar atentos as oportunidades de negócio que essas tecnologias tem a nos oferecer e tirar proveito disso.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Emerson Macedo] Seu software também deve comunicar-se corretamente

Wednesday, June 16th, 2010

Alguns estudos apontam que o maior problema da maioria das empresas é a comunicação. Esforços incansáveis são feitos para melhorar isso e todos sabemos que é um grande desafio. Mas e o Software? Será que este também não deveria comunicar-se de forma mais clara com seus usuários?

Exemplo triste – Aconteceu comigo :(

Ontem a tarde me aconteceu uma situação pouco comum. Após terminar o jogo do Brasil pela Copa 2010, fui com minha esposa ao supermercado fazer algumas compras. Compramos um bocado de coisas. Diria que fiquei mais de 1 hora no mercado. Na hora de pagar, eis que surge um problema. O cartão Alimentação Pass da Sodexo não funcionou. A máquina informou a seguinte mensagem: “FALHA NA COMUNICAÇÃO” (que imagino ser um problema de rede ou algo do tipo). A caixa do mercado repetiu o processo em outra máquina e o problema permaneceu. Até ai tudo bem. Afinal, indisponibilidade é algo que pode acontecer.

Passado alguns minutos, a caixa chamou o fiscal do mercado que nos atendeu de forma simpática e pegou uma outra máquina para tentar novamente fazer o pagamento (nesse momento eu já estava pensando em usar o cartão do banco de deixar pra lá o sodexo). Eis que a máquina informa que o saldo estava zerado, ou seja, teoricamente em alguma das passagens a compra foi paga. Percebi então que uma simples ida ao mercado ia me dar uma dor de cabeça sem tamanho.

O simpático fiscal, ao verificar o problema, foi a gerência da loja para tirar relatórios e verificar o que aconteceu. Voltando, a única coisa que saiu no relatório foram transações não concluídas. Nesse momento eu perguntei ao fiscal: O sistema não informa qual foi o problema? Ele me disse: Não, o sistema só informa que não foi relalizada. Acabei ficando sem saber o que estava acontecendo de fato, já que meu saldo estava zerado. A minha única certeza é que em algum lugar foi debitado a compra do meu cartão sodexo.

O próximo passo foi tentar verificar na sodexo. Abri meu iphone e entrei no site para verificar o saldo. Digitando o número do cartão e cpf, recebi a mensagem “Não foi encontrado um cartão para os dados informados”. Achei um pouco estranho e liguei para um amigo, passei meus dados e pedi para ele verificar, pois poderia ser que o site não oferecesse um comportamento correto no browser do iphone. Ele verificou e a mesma mensagem apareceu. Caiu a ficha. Estava acontecendo algum problema grave na Sodexo.

Liguei então para central de atendimento. O atendimento eletrônico me pediu o número de cartão e senha e em seguida me informou o saldo. Para minha surpresa, o saldo era o dobro do saldo que deveria ser, ou seja, nem estava zerado, nem estava correto. Comecei a falar com o atendente e pedi meu saldo novamente. Ele me disse: Seu saldo é zero. Retruquei: Como zero se o atendimento eletrônico me disse o saldo X? Ele respondeu: Houve uma queda geral nos sistemas e estamos dando o prazo de até as 00:00 de hoje para tudo voltar ao normal.

No fim das contas paguei com cartão de débito do banco.

Análise do problema.

Após esse incidente, pensei um pouco sobre esse sistema de pagamentos.

Sobre a compra, provavelmente o que aconteceu é que o Sodexo debitou o valor e como a máquina não respondeu e o sistema caiu, a transação deve ter ficado pendente, prendendo meu saldo. Nesse momento, fazia sentido não ter saldo até que o sistema fosse restabelecido por completo. Mesmo assim, alguma coisa me incomodou. Por que a mensagem de retorno não poderia informar o que estava acontecendo? Não poderia informar alguma coisa melhor que “FALHA NA COMUNICAÇÃO”? Naquela hora, eu não sabia se o problema era da Sodexo, que não informava um código/retorno de erro adequado, ou se a máquina não tratava os retornos de erros corretamente.

Enviar mensagens de erro corretamente e fazer tratamento de forma adequada são fundamentais na comunicação com o usuário, quando o sistema apresenta comportamentos inesperados. A falta de atenção nisso é mais comum do que parece e vou exemplificar. Existem diversos sistemas que ignoram mensagens, como por exemplo situações onde um dos lados (ou ambos) em uma comunicação  ignoram os status code http. Ex:

HTTP/1.1 200 OK
Content-Type: text/xml

<error>
  <code>123</code>
  <message>Ocorreu um erro</message>
</error>

Percebeu o problema?

Outro caso bem comum acontece quando quem envia uma mensagem para um objeto trata todos os retornos de erros de forma igual e não mostra claramente a mensagem. Ex:

try {
  objeto.fazAlgumaCoisa();
catch (Exception e) {
  log.error("Deu algum erro");
}

Já vi muito código assim e isso dificulta bastante pra quem está tentando entender o que está acontecendo.

Pior que isso foi o sistema web me dizer que não achou meu cartão, quando na verdade algum outro sistema que esse se comunica estava fora do ar. Não podia simplesmente informar algo como “Nosso sistema está em manutenção, previsão de retorno para X horas”? Cartão inexistente é inadmissível, pois certamente o cliente ficará confuso sobre o que está acontecendo.

E o saldo no atendimento eletrônico que estava dobrado? Eu aprendi certa vez que esse tipo de informação deveria vir de somente um lugar. No caso eu obtive 3 valores diferentes para meu saldo, o que me indica que esse principio não foi respeitado.

E sobre a indisponibilidade do sistema? Que tal enviar automaticamente um SMS/twitter/email ou qualquer outra coisa para que os clientes possam se preparar para esse tipo de situação? Ser pego de surpresa é sempre ruim.

Conclusão

Comunicação não é só importante entre pessoas. Nossos Softwares precisam comunicar-se adequadamente com seus usuários. Muitos ignoram isso completamente. Tenho certeza que podemos melhorar isso.

[Emerson Macedo] Seu software também deve comunicar-se corretamente

Wednesday, June 16th, 2010

Alguns estudos apontam que o maior problema da maioria das empresas é a comunicação. Esforços incansáveis são feitos para melhorar isso e todos sabemos que é um grande desafio. Mas e o Software? Será que este também não deveria comunicar-se de forma mais clara com seus usuários?

Exemplo triste – Aconteceu comigo :(

Ontem a tarde me aconteceu uma situação pouco comum. Após terminar o jogo do Brasil pela Copa 2010, fui com minha esposa ao supermercado fazer algumas compras. Compramos um bocado de coisas. Diria que fiquei mais de 1 hora no mercado. Na hora de pagar, eis que surge um problema. O cartão Alimentação Pass da Sodexo não funcionou. A máquina informou a seguinte mensagem: “FALHA NA COMUNICAÇÃO” (que imagino ser um problema de rede ou algo do tipo). A caixa do mercado repetiu o processo em outra máquina e o problema permaneceu. Até ai tudo bem. Afinal, indisponibilidade é algo que pode acontecer.

Passado alguns minutos, a caixa chamou o fiscal do mercado que nos atendeu de forma simpática e pegou uma outra máquina para tentar novamente fazer o pagamento (nesse momento eu já estava pensando em usar o cartão do banco de deixar pra lá o sodexo). Eis que a máquina informa que o saldo estava zerado, ou seja, teoricamente em alguma das passagens a compra foi paga. Percebi então que uma simples ida ao mercado ia me dar uma dor de cabeça sem tamanho.

O simpático fiscal, ao verificar o problema, foi a gerência da loja para tirar relatórios e verificar o que aconteceu. Voltando, a única coisa que saiu no relatório foram transações não concluídas. Nesse momento eu perguntei ao fiscal: O sistema não informa qual foi o problema? Ele me disse: Não, o sistema só informa que não foi relalizada. Acabei ficando sem saber o que estava acontecendo de fato, já que meu saldo estava zerado. A minha única certeza é que em algum lugar foi debitado a compra do meu cartão sodexo.

O próximo passo foi tentar verificar na sodexo. Abri meu iphone e entrei no site para verificar o saldo. Digitando o número do cartão e cpf, recebi a mensagem “Não foi encontrado um cartão para os dados informados”. Achei um pouco estranho e liguei para um amigo, passei meus dados e pedi para ele verificar, pois poderia ser que o site não oferecesse um comportamento correto no browser do iphone. Ele verificou e a mesma mensagem apareceu. Caiu a ficha. Estava acontecendo algum problema grave na Sodexo.

Liguei então para central de atendimento. O atendimento eletrônico me pediu o número de cartão e senha e em seguida me informou o saldo. Para minha surpresa, o saldo era o dobro do saldo que deveria ser, ou seja, nem estava zerado, nem estava correto. Comecei a falar com o atendente e pedi meu saldo novamente. Ele me disse: Seu saldo é zero. Retruquei: Como zero se o atendimento eletrônico me disse o saldo X? Ele respondeu: Houve uma queda geral nos sistemas e estamos dando o prazo de até as 00:00 de hoje para tudo voltar ao normal.

No fim das contas paguei com cartão de débito do banco.

Análise do problema.

Após esse incidente, pensei um pouco sobre esse sistema de pagamentos.

Sobre a compra, provavelmente o que aconteceu é que o Sodexo debitou o valor e como a máquina não respondeu e o sistema caiu, a transação deve ter ficado pendente, prendendo meu saldo. Nesse momento, fazia sentido não ter saldo até que o sistema fosse restabelecido por completo. Mesmo assim, alguma coisa me incomodou. Por que a mensagem de retorno não poderia informar o que estava acontecendo? Não poderia informar alguma coisa melhor que “FALHA NA COMUNICAÇÃO”? Naquela hora, eu não sabia se o problema era da Sodexo, que não informava um código/retorno de erro adequado, ou se a máquina não tratava os retornos de erros corretamente.

Enviar mensagens de erro corretamente e fazer tratamento de forma adequada são fundamentais na comunicação com o usuário, quando o sistema apresenta comportamentos inesperados. A falta de atenção nisso é mais comum do que parece e vou exemplificar. Existem diversos sistemas que ignoram mensagens, como por exemplo situações onde um dos lados (ou ambos) em uma comunicação  ignoram os status code http. Ex:

HTTP/1.1 200 OK
Content-Type: text/xml

<error>
  <code>123</code>
  <message>Ocorreu um erro</message>
</error>

Percebeu o problema?

Outro caso bem comum acontece quando quem envia uma mensagem para um objeto trata todos os retornos de erros de forma igual e não mostra claramente a mensagem. Ex:

try {
  objeto.fazAlgumaCoisa();
catch (Exception e) {
  log.error("Deu algum erro");
}

Já vi muito código assim e isso dificulta bastante pra quem está tentando entender o que está acontecendo.

Pior que isso foi o sistema web me dizer que não achou meu cartão, quando na verdade algum outro sistema que esse se comunica estava fora do ar. Não podia simplesmente informar algo como “Nosso sistema está em manutenção, previsão de retorno para X horas”? Cartão inexistente é inadmissível, pois certamente o cliente ficará confuso sobre o que está acontecendo.

E o saldo no atendimento eletrônico que estava dobrado? Eu aprendi certa vez que esse tipo de informação deveria vir de somente um lugar. No caso eu obtive 3 valores diferentes para meu saldo, o que me indica que esse principio não foi respeitado.

E sobre a indisponibilidade do sistema? Que tal enviar automaticamente um SMS/twitter/email ou qualquer outra coisa para que os clientes possam se preparar para esse tipo de situação? Ser pego de surpresa é sempre ruim.

Conclusão

Comunicação não é só importante entre pessoas. Nossos Softwares precisam comunicar-se adequadamente com seus usuários. Muitos ignoram isso completamente. Tenho certeza que podemos melhorar isso.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Emerson Macedo] No Limite, Lata Velha e uma plataforma que nasce

Wednesday, May 5th, 2010

Quem é telespectador da TV Globo já está acostumado com os diversos programas de TV que oferecem a oportunidade de participação ao público. Geralmente esses programas abrem uma inscrição através do envio de uma carta ao programa, email, download de um formulário para preenchimento, etc.

Nos últimos anos, alguns sistemas foram construídos para melhorar esse canal de casting (i.e seleção de pessoas)desses programas para a TV Globo. Porém, a cada iniciativa nova de casting por parte de um programa, era necessário criar um novo sistema de acordo com as necessidades. Até ai tudo bem, afinal de contas cada programa tem uma necessidade específica. Por muito tempo, usamos também o nosso 8p para ajudar nesse sentido, inclusive para clientes importantes, como Musas do Brasileirão e Big Brother Brasil.

Passado algum tempo, percebemos alguma semelhança entre as iniciativas de casting. Em sua maioria, a opção era um formulário de perguntas e respostas e o envio de um vídeo. Sendo assim, resolvemos desenvolver uma solução para possibilitar o cliente criar uma nova campanha de casting em alguns dias.

De toda essa experiência, criamos um projeto chamado Plataforma de Participações, com o objetivo de oferecer aos nossos clientes da TV essa forma simples de criar campanhas. Basicamente quem monta uma campanha hoje pode escolher se tem formulário, vídeo ou ambos e pode fazer uma definição completa do seu formulário (caso exista), configurando cada pergunta e seu tipo de resposta, precisando de pouca ajuda técnica para colocar sua campanha de casting no ar. Cada cliente também personaliza seu header, preservando assim a identidade visual da sua marca.

Como todo produto ágil, existem outras features no backlog para atenderem algumas demandas dos nossos clientes.

Nossos primeiros clientes são o No Limite e o Lata Velha do Caldeirão do Huck que já estão no ar há algumas semanas e mostrando que essa Plataforma de Participações tem se comportado muito bem nesse começo.

[Emerson Macedo] No Limite, Lata Velha e uma plataforma que nasce

Wednesday, May 5th, 2010

Quem é telespectador da TV Globo já está acostumado com os diversos programas de TV que oferecem a oportunidade de participação ao público. Geralmente esses programas abrem uma inscrição através do envio de uma carta ao programa, email, download de um formulário para preenchimento, etc.

nolimite No Limite, Lata Velha e uma plataforma que nasce

Nos últimos anos, alguns sistemas foram construídos para melhorar esse canal de casting (i.e seleção de pessoas)desses programas para a TV Globo. Porém, a cada iniciativa nova de casting por parte de um programa, era necessário criar um novo sistema de acordo com as necessidades. Até ai tudo bem, afinal de contas cada programa tem uma necessidade específica. Por muito tempo, usamos também o nosso 8p para ajudar nesse sentido, inclusive para clientes importantes, como Musas do Brasileirão e Big Brother Brasil.

Passado algum tempo, percebemos alguma semelhança entre as iniciativas de casting. Em sua maioria, a opção era um formulário de perguntas e respostas e o envio de um vídeo. Sendo assim, resolvemos desenvolver uma solução para possibilitar o cliente criar uma nova campanha de casting em alguns dias.

De toda essa experiência, criamos um projeto chamado Plataforma de Participações, com o objetivo de oferecer aos nossos clientes da TV essa forma simples de criar campanhas. Basicamente quem monta uma campanha hoje pode escolher se tem formulário, vídeo ou ambos e pode fazer uma definição completa do seu formulário (caso exista), configurando cada pergunta e seu tipo de resposta, precisando de pouca ajuda técnica para colocar sua campanha de casting no ar. Cada cliente também personaliza seu header, preservando assim a identidade visual da sua marca.

lata velha No Limite, Lata Velha e uma plataforma que nasce

Como todo produto ágil, existem outras features no backlog para atenderem algumas demandas dos nossos clientes.

Nossos primeiros clientes são o No Limite e o Lata Velha do Caldeirão do Huck que já estão no ar há algumas semanas e mostrando que essa Plataforma de Participações tem se comportado muito bem nesse começo.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Emerson Macedo] Não se apaixone pela sua tecnologia

Wednesday, February 3rd, 2010

Cansado das briguinhas recentes em listas de discussão, blogs e foruns sobre Ruby x Python, resolvi escrever sobre o assunto de forma totalmente imparcial. Serei imparcial, não por causa do blog, mas porque com esse tipo de assunto eu sempre geralmente sou imparcial, pois pela diversidade de empresas que trabalhei durante os meus mais de 12 anos de carreira, acabei sempre trabalhando com as 2 linguagens que eram o motivo da briguinha, em cada época distinta.

No início

Em meados de 1997/1998, pouco antes da bolha da internet, quando eu comecei a trabalhar profissionalmente, eu trabalhava com eletrônica e informática em uma empresa de automação de ponto e acesso. Tive a oportunidade de usar Delphi para desenvolver um protótipo de sistema integrado ao hardware de ponto e acesso dessa empresa, pois eles usavam um programas DOS para extrair dados e jogar num arquivo texto, e o outro programa DOS fazia a leitura desse arquivo para gerar o resuldado de ponto e o acesso. Foi uma experiência ótima, pois meu protótipo acessava diretamente o equipamento pela porta serial e já mostrava as informações em tempo real. Essa idéia foi pouco tempo depois usada pela fábrica para novas versões do software.

Nessa época, a programação desktop ainda reinava e as opções mais comuns eram Delphi e Visual Basic, então sempre algum colega ou outro puxava a sardinha pro lado do Delphi ou do VB. Nessa época, confesso que eu era meio bobo no assunto e eu acabava entrando na onda também, principalmente falando mau do coitado do VB. Tempos depois acabei trabalhando com VB em outros lugares e pude perceber que existia aplicação para ele dependendo do caso. Confesso que sempre gostei mais do Delphi, mas nesse momento eu deixava de ser um apaixonado e passava a fazer a escolha de forma mais racional.

Surge o desenvolvimento pra Web

Quando começei a trabalhar com web em meados de 2000, trabalhei com PERL, depois ASP e ColdFusion. Nesse tempo, surgiu a versão Beta do DotNET em 2001. Foi quando comecei a desenvolver aplicações desktop em WindowsForms e alguma coisa web, com o objetivo de aprender.

Passado pouco tempo e fui trabalhar numa empresa onde usavam tudo da Microsoft. Java nem pensar nessa empresa. Todos falavam mau da Sun e do Java. Nessa época eu já estava bem escaldado com isso e não ia cair nessa novamente, perdendo meu tempo discutindo sobre quem era melhor, Java ou DotNET.

Passado mais um tempo, fui para uma outra empresa onde tinha projetos em DotNET, mas também tinha projetos Java. Como eu já estava estudando Java fazia um tempo, era uma ótima oportunidade para por em prática em algum projeto. Assim que surgiu uma vaga, me ofereci para entrar num projeto de um grande ecommerce brasileiro (que por algumas questões não posso citar o nome). Esse projeto foi ótimo para eu por em prática meus conhecimentos de Java. Nesse momento eu percebi que o pessoal de Java também gostava de falar mau do pessoal de DotNET. Na minha mente estava bem claro que isso era pura perda de tempo, pois claramente nos projetos que eu havia trabalhado eu pude perceber o valor de cada uma dessas tecnologias em cada contexto.

Passou o tempo e acabei não trabalhando mais com DotNET. As empresas seguintes foram todas com Java, exceto aqui na globo.com, onde voltarei a falar mais pra frente.

Muitos FUDs

Uma coisa que sempre percebi nessas brigas é que raramente usava-se argumentos lógicos e bem fundamentados. Geralmente as discussões eram baseadas em achismos e usavam algum argumento falacioso ou duvidoso/pouco claro.

Quando trabalhei para algumas empresas de Telecomunicações, Bancos e Seguradoras aqui no Rio de Janeiro, quase sempre havia um bom legado em COBOL e seus velhinhos de plantão dando manutenção nesses sistemas. Volta e meia eu ouvia algo do tipo: “Esse negócio de Java é apertar botãozinho e ta tudo pronto. Homem que é homem programa em COBOL”. Isso não fazia o menor sentido e por mais que eu tentasse explicar pros caras que não era bem assim, não adiantava, já existia uma opinião sem fundamentos formada na cabeça deles.

Numa dessas últimas empresas que trabalhei (para um dos maiores Bancos do nosso país), eu era Arquiteto junto com mais 14 desenvolvedores em um projeto Java que precisava se comunicar com programas COBOL/CICS. Sabe o que os COBOLEIROS diziam? “Só usem java pra pegar o que for processado aqui no COBOL porque aqui é que aguenta o tranco. Esse negócio de Java só serve para a parte levinha“. Apesar de conhecer sobre todo o poder de processamento dos Mainframes, eu sabia que aquilo era apenas uma provocação, pois eu já havia trabalhado em sistemas web feitos com Java com volumes bem maiores que os desse sistema e tudo correu muito bem. Sendo assim, nem entrei em discussão sobre isso, pois eles já tinham se fechado para o assunto.

Nossos dias atuais

Hoje em dia está muito na moda o uso de linguagens dinâmicas como Ruby e Python para desenvolvimento de software, muitos deles aplicações web. Existem diversos casos de sucesso usando essas tecnologias, e mais uma vez surgem as brigas pra saber qual é a melhor: Ruby ou Python.

Não espere aqui uma opinião minha sobre o que é melhor entre as 2, pois isso não vai acontecer. Não porque eu não tenha preferências, mas simplesmente porque melhor ou pior sempre dependerá do contexto e não somente da tecnologia.

Python é uma linguagem muito usada no mundo opensource, tendo muitos aplicativos console e desktop desenvolvidos para linux. A primeira versão do Youtube foi escrita em Python (não sei se ainda é). O Google AppEngine apesar de suportar Java, foi construido para Python. Existem diversas iniciativas que usam Python e são bem sucedidas.

Ruby apesar de ser uma linguagem bem antiga (1993), só explodiu mesmo com a chegada do Rails (2004/2005). Antes disso ninguém ouvia falar de Ruby. Mesmo assim, Rails trouxe uma ascensão meteórica para o Ruby, surgindo um ecosistema incrível, com uma série de produtos bem sucedidos e documentações fantasticas, screencasts, entre outros. Destacou-se muito com as ferramentas de testes automatizados que tanto precisamos hoje em dia para desenvolvermos software com qualidade.

No time onde eu trabalho na globo.com, desenvolvemos projetos em Java, em Python/Django e Ruby on Rails (projeto atual). Cada uma das escolhas teve razões lógicas e seus benefícios (que se comprovaram). Essa versatilidade faz com que esse time possa trabalhar em praticamente qualquer projeto da empresa, já que tem conhecimento nas principais linguagens que a empresa trabalha. Isso é muito mais benéfico do que ficar preso a uma tecnologia, defendendo-a com unhas e dentes.

O Mito do não escala

Com o advento dessas linguagens dinâmicas, deu bem pra perceber como a maioria dos profissionais não entendia/não entende quase nada sobre escalabilidade de sistemas web. Assim como o COBOLEIRO falava que o Java não aguentava o tranco, começaram a falar que linguagens dinâmicas não escalavam, principalmente o famoso “Rails não escala”.

Certa vez eu lí um post de 2004 (antes do Rails) que já falava sobre esse mito de não escala. Vale a pena conferir aqui. E tem também um screencast mais recente(baixe o vídeo e assista) do Gregg Pollack que nos primeiros minutos mostra na maioria das vezes o que deixa um site lento. Dica: tem pouco a ver com a tecnologia usada.

Portanto, não caia nessa. Pesquise e aprenda como escalar sua aplicação, independente de você estar usando Python/Django Ruby/Rails, Java, DotNET ou qualquer outra tenologia do seu projeto.

Conclusão

Mesmo com essas 2 tecnologias (Ruby e Python) fazendo seu sucesso nos dias de hoje e tendo seu contexto para serem aplicadas, o pessoal ainda continua brigando pra defender a sua tecnologia preferida. Parece que cria-se uma paixão cega pela linguagem, como se fosse uma espécie de religião, saindo do racional e passando a ser totalmente irracional.

Dessa forma, meu conselho para todos os profissionais é que não entrem nessa de ficar defendendo sua tecnologia preferida e atirando pedra na tecnologia concorrente. Aprenda ambas e saiba onde e quando usar cada uma delas.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.