Screencast – Controller Dialog

Galera, vai um post rápido porque já faz um tempo que o blog tá meio parado.

Fiz um screencast usando a versão mais atual do Jails, bem mais maduro, usando Webpack e o ES6. Demorou um tempo para adotar o ES6 confesso, muito mais pelo fato de esperar que os transpilers ficassem mais maduros e mais estáveis. Assim como as especificações sobre o ES6, definições do que seria o draft, quais seriam os presets etc.

É claro que aconselho usarem o ES6 assim como o Webpack, é um grande avanço principalmente para os que ainda estão um pouco parados nos paradigmas antigos.

Existe uma série de vantagens em usar o ES6 hoje, bem como ferramentas fantásticas como o Webpack, quem não conhece ou ainda não mexeu, fica a dica =).

Screencast

Esse screencast ficou um pouco longo, também percebi alguns erros depois de pronto, mas estou com muita preguiça de editar =/. Peço que ignorem os erros de português, onde falo “internalização” entenda por “internacionalização” etc.

A idéia do vídeo é mais mostrar um pouco de como é programar usando a lógica do Jails, como separar os problemas e de quebra um pouco de código em ES6. Valeu!

Anúncios

Javascript e um Sistema Tolerante à Falhas

Sistema tolerante à falhas é uma das matérias da Ciência da Computação que eu menos gostei, ao mesmo tempo foi o que mais me chamou a atenção, porque embora fosse uma matéria muito maçante, muito baixo nível, ela tem uma visão que pode ser perfeitamente usada no front-end, no Javascript.

Javascript Exceptions

Toda vez que depara com um erro de javascript no browser significa que uma Exception foi lançada e nenhum mecanismo no seu sistema soube tratar ou capturar esta exception, no final sobra para o Browser resolver o que fazer com aquilo, geralmente é “logando” no console a mensagem de erro.

Tudo bem, pode ser que isso não seja novidade para a maioria, mas o que a gente não pára pra analisar é.

  • Como poderíamos tratar os erros no javascript
  • Como identificar os pontos do seu código que pode quebrar
  • Qual a importância disso?

Consequência de um erro não tratado

Bom, o porque de ser importante no mínimo pensar sobre o assunto é fácil de entender usando bom e velho exemplo de uma aplicação do Twitter.

Eu não conheço nada da regra de negócios da aplicação do Twitter e a abstração a seguir é apenas para ilustrar, digamos que separemos os módulos da aplicação como mostrado na imagem, numa arquitetura modular:

Screen Shot 2015-11-09 at 20.50.39

Imagine que o seu primeiro módulo, lá na barra de status no topo esquerdo quebre, ou seja, lance uma exception não tratada no momento que é iniciado. Se sua arquitetura executa os módulos de forma sequencial, isto significa que este é o primeiro módulo a ser executado e portanto, nenhum outro vai ser executado à partir deste ponto.

Ruim né? Ou seja, NADA irá funcionar e no pior das hipóteses, dependendo de como implementa o conteúdo da parte central, se esta for totalmente dependente de Javascript, ficará comprometida e totalmente em branco!!!.

Isso acontece em parte porque o Javascript é interpretado, de forma sequencial, ele não é compilado e portanto seus erros  ocorrerão em tempo de execução, a partir dali todo o resto do código é comprometido e o interpretador não sabe o que fazer com aquilo.

O que poderíamos fazer?

Eu não tenho a pretensão de ensinar você como tratar erros da melhor forma no Javascript, primeiro porque não tenho tanta competência no assunto e outra porque é extremamente subjetivo, cada caso é um caso, mas posso mostrar algumas idéias à partir de alguns pontos de STF ( Sistema Tolerante à Falha ) que aprendi, de maneira muito artificial e um pouco mais didática e prática.

Não vou usar os jargões da matéria como confiabilidade, resiliência etc etc.. isso é bem chato, eu boto um link no final para caso queiram aprofundar no assunto.

No caso do Twitter, imagina que sua arquitetura modular possui padrões, e uma delas é que o módulo sempre é iniciado através de uma chamada .init(). Já é uma pista certo? Na situação anterior, identificamos que o carregamento destes módulos é uma situação crítica, portanto precisamos tratar TODOS os possíveis erros que acontecem no momento da inicialização, essa é a segunda pista.

Então você pode pensar que isso é a coisa mais fácil de fazer, você conhece seu código, “sabe” onde pode dar bosta, certo? Claro que não.

Um módulo pode iniciar uma série de scripts, inclusive scripts de terceiro. E é aí que o perigo mora. Você conhece 100% o que o script de terceiro faz no seu código? Seja uma chamada do google analytics, seja uma biblioteca para resolver um determinado problema, você sabe todas as possíveis situações onde seu script pode quebrar?

Não, não sabe. Mas temos pistas suficientes para dizer que este é um ponto crítico, ao mesmo tempo que não sabemos exatamente que erro pode acontecer, portanto a solução poderia ser esta:

var module;

for( var i = 0, len = modules.length; i > len; i++ ){ 
    module = modules[i]; 
    try{ module.init(); }
    catch(e){ 
        myLogger.log('Erro de inicialização de módulo =>', module.name, e);
    }
}

É simples né? Resolve todos os problemas do mundo e agora seu sistema é totalmente tolerante à falhas? Lógico que não, mas esta besteirinha faz com que sua aplicação seja um pouco mais tolerante, menos frágil.

Esta pequena mudança simplesmente  garante que os outros módulos funcionem de forma independente no momento de inicialização, e se sua arquitetura é realmente modular, o usuário pode nem perceber que seu módulo de notificações está com problemas! Olha que maravilha. E tem ainda mais um ganho, muitas vezes os erros acontecem e o browser te dá esta dica:

Undefined is not a function

Na linha x, na coluna y, do script third-party, ou de uma biblioteca, tipo jQuery… e aí?

O tratamento de erro do try/catch ainda de quebra te dá uma mensagem mais amigável, dizendo exatamente quando e qual módulo quebrou, dando um mínimo de informação relevante.

Exceptions “assíncronas”

Mas você pode se perguntar do por que em alguns casos um determinado erro no seu javascript não influencia seu sistema como um todo. Sabe quando (quase) tudo está funcionando perfeitamente e você percebe que há um erro no console ?

Isso ocorre porque seu código já carregou e executou perfeitamente, porém existem erros em trechos de códigos assíncronos como um calback de um ajax, ou um evento de click por exemplo. Neste último caso, o trecho de código será executado e avaliado pelo interpretador apenas no momento do clique, é um outro “stack”, portanto não vai influenciar na inicialização dos seus módulos, mas irá influenciar todo o código posterior ao erro neste evento. Um exemplo, um caso clássico, aposto que já passou por isso alguma vez:


$('.module a').click( request );

function request(e){

    e.preventDefault();
    _gaq.push(['_trackEvent', 'name', 'some value']);

    module.get('my/service/').done( callback );
};

Quem nunca? Existem dois problemas em potencial aí neste código, o primeiro é se por algum motivo alguém remove o analytics da página, o que seria por si só um problema sério ou o google muda a api, raro acontecer sem aviso prévio, mas dependendo do script pode acontecer.

O segundo, mais frequente, é se alguem chamar o .request() de maneira independente ao invés de passar a função como parâmetro para ser usado como um handler de evento. Neste caso, não existe a variável de evento, então a chamada do e.preventDefault() não irá funcionar.

São duas práticas ruins, mas de qualquer forma, estes problemas não deveriam inutilizar seu módulo, pensando num sistema mais tolerante à falhas.

A forma mais rápida de permitir que seu sistema não fique tão frágil, seria colocar scripts de prioridade baixa pro final, porque se aquele script quebra, não vai fazer com que seu módulo pare de funcionar.

Você também não deveria colocar try/catch em todos os trechos do seu código, isso certamente em alguma situação prejudicaria tanto a manutenção e legibilidade do seu código, como também a performance da sua aplicação.

Nesse caso, desacoplar tanto o handler de evento quanto a implementação do analytics seria interessante, assim como testar se as variáveis existem.

Mas o que eu quero mostrar aqui é que há casos onde não é tão simples assim enxergar trechos sensíveis à bugs, é por isso que não existe uma fórmula de como proteger seu código, mas que vale a pena enxargá-lo com outros olhos à partir de agora.

Outra coisa importante é perceber que os erros podem ser tratados e revertidos. Por exemplo, um ajax que falha na requisição.

Você pode informar o usuário de que a ação falhou e pedir que ele tente novamente, ou em alguns casos, se percebe que existe uma certa instabilidade em um serviço, você pode fazer uma segunda tentativa de forma transparente ao usuário. Ele não vai notar que ouve um erro, dependendo de alguns fatores de conexão, pode ser até que ele mal perceba que ouve um tempo maior de espera, já que foram feitas duas requisições ou até três. Se você usa celular, provavelmente já passou por esta situação como usuário inúmeras vezes e não percebeu nada.

Abrindo a mente…

Um dos problemas que eu queria resolver no desenvolvimento das minhas aplicações é começar a me preocupar com problemas deste tipo, como melhorar a experiência do usuário e programar de forma, vamos dizer, mais profissional.

Eu não conseguia fazer isso porque a maior parte do tempo estava lutando com a arquitetura mal feita de alguma aplicação/site, ou implementando do zero um componente que já deveria estar pronto, ou perdendo tempo fazendo coisas do zero, quando deveria apenas me preocupar com problemas mais alto nível, como Tolerância à falhas.

Bom, eu havia dito num post anterior que havia conseguido melhorar minha arquitetura consideravelmente com o Jails e poderia me preocupar com outras coisas já que agora posso reutilizar mais o código. Portanto tenho tempo para pensar em melhorias como esta, ao invés de me preocupar com problemas corriqueiros.

Isto abre uma nova perspectiva sobre o que eu estou desenvolvendo e como estou desenvolvendo, abrindo novas posssibilidades.  Estou construindo um módulo chamado Throwable que se beneficia da arquitetura do Jails e automatiza o processo de lançar e tratar erros, um problema que nunca dei atenção no Javascript.

No próximo post, vou mostrar este módulo, que já deve estar numa versão mais beta e dar algumas idéias e formas diferentes de como deixar o tratamento de erros um pouco mais elegante e seu sistema mais tolerante à falhas.

Tudo o que aprendi sobre tratamento de erros no javascript, foi lendo algumas apresentações e artigos do Nicholas Zakas, um cara brilhante que se você não conhece, deveria conhecer. Ele já fala sobre arquitetura modular faz 1 milhão de anos.

Pode ignorar tudo o que escrevi, mas leia estes conteúdos sobre tratamento de erros no javascript dele, vai ganhar muito!

Sobre STF:

http://www.inf.ufrgs.br/~taisy/disciplinas/textos/ConceitosDependabilidade.PDF

http://www.cin.ufpe.br/~jvob/introducao.html

 

 

Novo release do Jails 1.0.0 e a experiência de escrever um framework

Fala meu povo!

Eu às vezes me sinto um pouco babaca escrevendo aqui pra mim mesmo ahahhaahah. Mas se você é um dos poucos que acompanham este blog parado tenho uma boa notícia!

Acabei de lançar a última versão do Jails, projeto de arquitetura AMD que comecei faz algum tempo já. Não imaginava que fosse chegar à esse ponto, não tinha a mínima idéia o quanto ela evoluiria desde a sua concepção lá no início. Me lembro que pensava que se eu utilizasse ela na versão 0.0.2 ( lá no comecinho ) eu iria melhorar muito meus projetos… Mal sabia o quanto ela ainda iria melhorar.

Jails 1.0.0 ( Orpheus )

Bom, todos os releases tem um codinome baseado em alguma figura mitológica, é por isso o nome estranho ali. Mas falando do que mais importa, esta versão é estável e totalmente reescrita do zero.

Quando você tem uma idéia, você a rabisca, faz rascunhos primeiro, depois lapida, testa, gera algumas versões e vê como ela se comporta em um cenário em produção.

Bom foi isso que eu fiz basicamente, quando ela se tornou promissora e realmente fazia sentido ser usada, decidi então reescrever usando os mesmos conceitos, porém melhorando a parte técnica do código. Isso faz com que melhore tanto na performance, quanto na manutenção, e abrindo novas possibilidades ao mudar algum approach.

Independente do jQuery/Zepto

Esta foi uma tarefa bem difícil pois ao contrário do que a maioria pensa, trabalhar sem jQuery é complicado. Dar suporte à maioria dos browsers não é uma tarefa fácil. O Jails ainda não dá suporte à maioria deles, mas uma característica nesta versão faz com que você acople bibliotecas nela que faz com aumente o espectro de compatibilidade. Por exemplo, se usar um Adapter jQuery 1.11 ela vai dar suporte à todos os browsers que esta versão do jQuery dá.

Repositórios – Components & Modules

No começo eu estava tão empolgado com a idéia que queria inflar o repositório com módulos e componentes. Com esta nova versão, percebi que a maioria deles tinha dependência com o jQuery/Zepto, mas não precisariam ter.

Não foi só a biblioteca que foi ganhando maturidade, mas eu também, ao utilizá-la no dia-a-dia e percebi que ao invés de ter repositórios lotados de componentes e módulos beta, eu deveria me preocupar mais com a qualidade dos componentes/módulos que eu estava escrevendo.

Eles também ganharam uma interface um pouco mais bonita, um lugar para buscar e ler sobre a documentação e ver exemplos.

Compartilhando Exemplos

No início eu hospedava em cada módulo/componente os exemplos que fazia. Isso começou a fazer menos sentido conforme fui amadurecendo o projeto, não fazia sentido criar uma série de exemplos e ficar commitando no github…( Ahh vá !! ) Oras… pra que serve jsfiddle, codepen, plunker? Então agora, os exemplos são todos hospedados nestes serviços..

Mas, existe um caso que vale a pena ser hospedado. Alguns projetos eu fazia e deixava na minha máquina, eram aplicações para testar o funcionamento e comportamento do Jails. Existem mais arquivos, e são mais complicados de serem testados em serviços de compartilhamento de código pelo fato destes serviços serem mais lentos por estarem na nuvem.

Então criei um repositório chamado Demos e lá ficam estas aplicações, no momento existem apenas duas, uma aplicação Flickr usando o serviço JSONP do próprio, e uma aplicação TodoMVC, um fork daquele projeto famoso.

Documentação…

É a parte mais chata de todas né… bom dei uma melhorada no padrão das documentações dos módulos e componentes, mas preciso ainda dar um grau na documentação do próprio Jails…

Por enquanto está lá meio capenga na wiki do projeto, mas acho que a wiki do github não tem um apelo visual dos melhores.. Acho que vou melhorar esta documentação e usar o bom e velho gitbook.

Exército de um homem só

Nem preciso dizer que não tenho qualquer suporte e/ou contribuição né? Mas isso não é de fato o que me incomoda. O que realmente me incomoda é o fato de eu não conseguir ainda “vender” este projeto, mostrar o potencial dele para as pessoas…  então é o fato de ninguém realmente ter usado que me deixa mais angustiado…

Estou sofrendo do estigma de “mais um framework javascript” e lutar para ter a atenção que React, AngularJs, Ember, Backbone é certamente uma luta perdida, praticamente Davi vs Golias.

Motivação

Mas não se trata de ganhar uma luta, ou aparecer mais que os outros… Recebi alguns comentários, emails e stars no github que me motivaram a continuar. E não são só estas as minhas motivações.

O fato é que está FUNCIONANDO, não no sentido técnico, mas no sentido filosófico, está cada vez mais fazendo sentido escrever pequenos frameworks, pequenas bibliotecas. Eu realmente estou escrevendo menos código, estou conseguindo me divertir MUITO mais desenvolvendo e estou olhando para um código antigo feito em Jails com orgulho, e não mais com aquela sensação de que tudo ficou um lixo. Inclusive pensando bem…era este meu objetivo principal.

Consigo ver agora nos projetos que utilizei o Jails, o que mais pode ser feito, ao invés de pensar em refactories. Ao invés de pensar em que módulo melhorar, pensar qual módulo poderia agregar mais ao site, como um notificador quando algum módulo do site quebra, como fazer um BI desacoplado, etc etc etc.

Agora penso muito mais em como posso agregar com outras soluções, ao invés de pensar em como posso destruir e começar tudo do zero. Mesmo que seja a única pessoa no mundo que esteja usando, já valeu MUITO à pena.

Eu já utilizei outros frameworks, outras arquiteturas, novas e antigas… já tentei de tudo. Posso dizer com um PUTA orgulho… Nenhum deles, até agora, me faz “dropar” essa iniciativa e migrar para outra solução. Simplesmente porque o projeto não mira as inovações do mercado, o projeto é pé no chão, simplicidade aqui é tudo, e a modularização faz com que qualquer coisa nova revolucionária e já consolidada, possa ser acoplada de maneira muito simples.

Posso mudar a micro-arquitetura das aplicações de acordo com o projeto, e não engessar todas elas numa única arquitetura. Mantendo sempre a simplicidade, acho que o projeto só tem a crescer mais e mais.

Abaixo cito uma das frases que mais tem feito sentido para mim nos últimos tempos, reflete a verdadeira essência do Jails, sempre penso nela quando vou refatorar o código do projeto, ou quando estou escrevendo um componente/modulo e penso que preciso colocar mais coisas:

…It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to subtract. 

Antoine de Saint Exupéry – Terre des Hommes (1939)

 

 

Jails + Riot – A React-Like view.

Olá meus queridos!

Queria mostrar como é interessante trabalhar numa arquitetura modular, uma vez que você expande suas possibilidades de forma ilimitada. O Jails vem de fábrica com uma view default, esta view é um componente que utiliza o Mustache como engine.

Mas você pode querer usar uma outra engine certo? Você não deveria ficar engessado ou poderia escolher outra forma de renderizar as coisas na tela.

Bom, neste post eu vos apresento o Riot.js. Para quem não conhece, eu sugiro muito que conheça, pois é um daqueles micro-frameworks muito bem feitos, bem documentado, pequeno, e muito muito útil.

Riot implementa Virtual DOM e Custom Tags… Isso mesmo fera… Exatamente aquilo que mais gostamos no React, e ainda o implementa em 3kb.

Para quem não conhece, Virtual DOM grosseiramente falando é uma forma de abstrair a árvore do DOM em uma estrutura de dados independente e muito mais rápido de manipular do que a árvore DOM do browser.

Ele basicamente faz o diff das coisas que alteraram nesta árvore e apenas atualiza o elemento no DOM que foi alterado, portanto, você consegue um ótimo ganho de performance.

Além disso, Riot permite criar uma CustomTag, e ainda da forma mais fácil do mundo, e ainda fica mais fácil usando o riot-view do Jails como wrapper:

Screen Shot 2015-06-20 at 12.24.27

Criar um TODO list é simples e o template html é tão simples quanto criar um código html:

Screen Shot 2015-06-20 at 14.00.58

Para saber mais, só acessar o repositório do componente.

Jails + Riot component

Abraços

Jails – Módulo Debugger

Depois de bastante tempo satisfeito com o framework, eu precisava testar sua modularidade com um desafio bastante interessante.

O Jails de fábrica não possui um debugger, eu não coloquei dentro do framework breakpoints pra disparar um evento caso algo não exista, caso algum componente não esteja na página, ou se você esqueceu de carregar alguma coisa. Isso porque não é papel do framework saber onde você errou.

O papel dele é bem claro, facilitar a composição dos seus componentes e abstrações do seu projeto AMD, apenas isso.

Mas todo o framework precisa de um debugger, de algo que te diga onde errou, e não precisa ser algo muito complexo, basta apenas um log avisando do que esqueceu, porque é impressionante o tempo que ficamos olhando para um código que não funciona por causa de uma besteira…

É por isso que escrevi o Module/debug no repósitório oficial do Jails, é bem rudimentar, deve evoluir com o tempo, mas já ajuda pacas!

Ficou até bonito a forma como ele mostra os erros, às vezes dá até vontade de fazer errado só pra ver o log xD.


Screen Shot 2015-06-13 at 21.47.25

É MUIIITO fácil de carregar e deixar ele rodando, é um módulo como qualquer outro, se quiser saber mais sobre como carregá-lo basta dar uma conferida no repositório.

https://github.com/jails-org/Modules/tree/master/debug

Um grande abraço!