TL;DR: se está familiarizado com os problemas de executar Rails no Windows e já sabe o que é o HttpPlatformHandler, porque devemos usar JRuby no Windows, pule direto pra seção Configurando Rails da forma Correta para Windows mais pra abaixo.

No dia 4/2 a Microsoft anunciou o módulo HttpPlatformHandler. Então, em 9/2, o conhecido blogueiro Scott Hanselman fez um blog post explicando como poderíamos usar esse módulo para servir uma aplicação Rails atrás do IIS 8. Depois de um comentário que fiz ele atualizou para demonstrar como servir uma aplicação Rails em cima do JRuby.

Quase 2 anos atrás fiz um artigo que teve muitos leitores sobre instalar Ruby no Ubuntu 12.04 LTS. Inclusive era o que eu estava usando até agora como ambiente de desenvolvimento no Vagrant. O bom é que dá pra desenvolver tudo sem problema algum nesse ambiente e é bem estável, mas resolvi atualizar o mesmo artigo para instalar no último Long Term Support do Ubuntu, o 14.04 LTS Trusty Tahr.

Para VPS pequenos, eu particularmente não me incomodo de usar RVM em single-user mode com Nginx+Passenger. Em particular eu instalo esse ambiente num Vagrant, então se for esse o caso, depois de instalar o Vagrant, faça assim:

1
2
3
vagrant init phusion/ubuntu-14.04-amd64
vagrant up
vagrant ssh

Este é um dos assuntos mais antigos que eu exploro neste blog. Muitos dos princípios, filosofias, pensamentos por trás disso estão nos meus famigerados (e longos) Off-Topic. Como são muitos anos de posts, resolvi compilar o que considero as bases do que todos precisam saber sobre esse longo bikeshedding chamado "processos e metodologias".

Comece simples com o artigo que empresta título a esta coletânea Processos e Metodologias não vão te Ajudar que publiquei nos blogs da Abril em 2011. Para começar entendendo o que são processos, metodologias e procedimentos.

Em muitos aspectos o ano de 2014 foi extremamente triste para a comunidade internacional de Ruby e para mim pessoalmente já que conheci os 3 pessoalmente.

A comunidade internacional de Ruby vira e mexe surge com alguns "dramas". Toda comunidade tem seus "dramas", mas os Ruby Dramas particularmente chamam a atenção das demais comunidades então de vez em quando vale a pena explorar alguns deles para explicar porque eles acontecem e quais as ramificações.

No último dia de 2014, Brian Shirai soltou um post unilateral entitulado "Matz's Ruby Developers Don't Use RubySpec and It's Hurting Ruby", onde ele explica porque é ruim o Core Team do MRI não usar regularmente o projeto RubySpec, vale a pena dar uma lida.

Como contexto, vale explicar que Brixen é quem herdou o manto da implementação Rubinius e também do projeto RubySpec, que tenta ser uma suíte de testes que define o comportamento do que é a "linguagem Ruby" para que implementações alternativas como o próprio Rubinius ou JRuby ou outras possam se basear. Os projetos originaram com Evan Phoenix, atual membro do Ruby Central e organizador das RailsConf. Digamos que Evan é mais "politicamente correto", Brian é mais "agressivo".

Update 30/12/2014: existe um bug/regressão no Ruby 2.2.0 que não existia no 2.2.0-preview1.Se estiver usando Rails 3.2 você deve encontrar o warning de "circular argument reference". Então não atualize pra 2.2.0 se estiver no Rails 3.2 ou use este patch que o Aman Gupta fez.

Como prometido pelo Ruby Core Team, novamente como presente de Natal, no dia 25 de dezembro de 2014 tivemos o lançamento do esperado Ruby 2.2.0. Para saber o que mudou veja este artigo da InfoQ.

Para começar, é bom lembrar que a versão 1.8.7 está terminada desde 2013 com o End of Life oficial.

A série 1.9 trouxe diversas mudanças drásticas estruturais que, embora não quebrem tanto em termos de sintaxe, quebram nas estruturas de dados, como suporte nativo a Unicode, nova sintaxe de hash, Fibers, por exemplo. Peter Cooper tem um Walkthrough que vale a pena dar uma olhada. As versões 1.9.1 (experimental), 1.9.2 (estável mas ruim) e 1.9.3 (a melhor da série) foram grandes avanços desde a série 1.8, tanto em funcionalidades quanto performance.

A série 2.0 trouxe keyword arguments, module prepend, lazy enumerators, refinements (experimental). E a série 2.1 trouxe refinements como feature estável, inteiros de 128bits, melhoria no cache de métodos (um grande problema numa linguagem dinâmica com classes abertas), e a introdução da primeira geração do Restricted Generational Garbage Collector (RGenGC). Eu fiz um artigo chamado O que tem de novo no Ruby 2.1? que explica um pouco mais disso. Também fiz um artigo chamado Indo de Ruby 1.8 e Rails 2.3 para Ruby 2.0 e Rails 3.2 cujas técnicas continuam válidas para as novas versões de Ruby e Rails.

O mais relevante desde a versão 1.9.3 (lançada em outubro de 2011), seguindo pra 2.0.0 (lançada em fevereiro de 2013), depois a série 2.1 (lançada em dezembro de 2013) e finalmente com a 2.2.0 (lançada agora em dezembro de 2014), são 3 anos de evolução rápida e constante do Garbage Collector e algumas estruturas internas importantes como method caching e symbols.

Assistam minha palestra sobre Garbage Collector de Ruby para entender o funcionamento exato:

Um problema que nos persegue há muito tempo são uploads. À primeira vista é algo simples:

  1. Coloque um form com multipart configura
  2. Coloque um campo de input tipo "file"
  3. Dê POST, o upload vai iniciar com o web server
  4. Quando o upload terminar o web server passa o arquivo pra aplicação, agora é só salvar no disco

Mas esse é o jeito ruim. Funciona muito bem pra coisas pequenas, mas tenha muitos usuários fazendo uploads de dezenas de megabytes (que é o tamanho de qualquer foto tirada em smartphones) e de repente seu servidor fica de joelhos. Tenha muitos usuários fazendo uploads em conexões toscas (3G) e de repente seu web server fica travado à merce de conexões lentas. E no caso do Heroku, com timeout fixo em 30 segundos, tudo é cancelado depois de um tempo.

Daí tem o problema de onde colocar os arquivos: se colocar em arquivos no disco do servidor, a hora que você precisar colocar um segundo servidor em load balancing, vai ter problemas. Ainda tem gente que acha uma boa idéia colocar binários em campos BLOB num banco de dados (NUNCA FAÇA ISSO!!!). A única solução decente é jogar em buckets do S3 ou outros storages em cloud, mas sua aplicação fica mais lenta ainda: primeiro esperando o upload do usuário e depois fazendo o upload pro cloud. Tudo parece piorar o problema!

Pensando nisso fiz um artigo explicando em detalhes o problema, chamado S3 Direct Upload + Carrierwave + Sidekiq. Não é uma forma simples mas funciona. Porém o criador do Carrierwave, Jonas Nicklas parece que se cansou desse e outros problemas mais inerentes ao Carrierwave e resolveu começar do zero. Ele criou e lançou recentemente a excelente gem REFILE.

TL;DR: Esqueça Paperclip, Carrierwave ou Dragonfly. Use Refile! Ele tem dezenas de opções como qual storage você quer usar e muito mais, mas neste post vou me limitar ao caso de uso mais comum: Direct Upload para o S3, sem carregar seu servidor/aplicação. Tão fácil que cabe num Small Bites.

Acho que esta vai ser realmente a primeira small bite versão miniatura mesmo! :-)

Kindle Paperwhite + Manga = Diversão

Alguns dias atrás o professor Rosenclever Gazono, do Centro Universitário de Volta Redonda, me enviou um email pedindo algumas opiniões que achei interessante compartilhar. Já conheci muitos professores durante minhas visitas a diversas faculdades do país e muitos tem as mesmas dúvidas, então espero que isso ajude um pouco.

A seguir, vou transcrever as perguntas do professor e minhas respostas.

Professor: Meu nome é Rosenclever, sou professor universitário atualmente ministrando as disciplinas de Análise e Projeto Orientado a Objetos (Basicamente UML, Padrões de Projeto e Metodologias ágeis) e Programação Orientada a Objetos 2 (Java para Web com JPA e JSF)

Pois bem, como você além de desenvolvedor hoje também exerce um papel de empresário e eu, por outro lado, estou na academia, buscando preparar profissionais para atuarem no mercado, sempre busco tentar atualizar meu conteúdo com a demanda do mercado e é muito comum ouvir de gerentes de TI, por meio da mídia, que existe um gap muito grande entre o que se ensina na academia e o que o mercado necessita...

Desta forma, gostaria de pedir sua contribuição no sentido de que eu possa ajudar meus alunos a saírem mais preparados para o mercado. Assim, gostaria de saber a sua opinião sobre as ementas das disciplinas que falei no início deste email...

No atual caos que são as opções no mundo Javascript para gerenciamento de dependências (CommonJS, AMD, ES6-modules), sistemas de build (Grunt, Gulp, Broccoli), pacotes (NPM, Bower) é fácil sermos contaminados com o velho "F.U.D." (Fear, Uncertainty, Doubt).

Asset Management é um problema praticamente todo resolvido no mundo Rails desde Fevereiro de 2009 (nós basicamente criamos o conceito). Mesmo assim, ainda temos que ouvir afirmações sem sentido como "precisamos consertar ou substituir o Asset Pipeline" e então nascem coisas como "requirejs-rails" ou receitas de como desabilitar o Sprockets e usar outras coisas. Em resumo: não faça isso.

Até eu fico sem paciência para participar dessas discussões porque, no final do dia, o que precisamos é da solução mais simples que funciona e podemos confiar. E sem mais delongas eu elejo a combinação ModuleJS e Rails-Assets como as melhores opções.

Antes de continuar vou assumir que você pelo menos leu (ou já conhece) os seguintes assuntos:

Essa frase aparece bastante no mundo ágil. A interpretação correta para os 4 princípios do Manifesto Ágil é o que ele mesmo diz: "Embora saibamos que exista valor no ítem da direita, valorizamos mais o da esquerda".

Mas essa frase é usada para justificar "não precisamos ter processos, basta deixar as pessoas escolherem" ou então "as pessoas escolhem, então vamos ter consenso pra tudo" - a falácia da organização democrática -, enfim, desculpas para justificar o não entendimento do valor de se ter processos.

Agile, derivado de Lean, é inteiramente baseado em processos. E o principal dos processos é o que o Lean original (não as derivações como Lean Startup ou Kanban) tem como pilar o "Kaizen", ou seja, "melhoria contínua", onde o hoje é pelo menos um pouco melhor do que ontem, onde o que fazemos é mensurável e por causa disso possível de dizer que hoje fizemos melhor do que ontem. O princípio é simples, a execução nem tanto. Se ainda não leu, veja os links deste parágrafo para entender esses princípios.

Agora vem a parte ruim: como falar sobre pessoas? Ou mais especificamente, sobre comportamento de pessoas?

Uma das grandes vantagens de usar o Heroku é poder rapidamente aumentar o tamanho dos dynos para aumentar a capacidade de requisições simultâneas que sua aplicação pode responder. Porém existe um grande problema: você só vai pode aumentar suas dynos até o limite de conexões do seu banco de dados.

Para isso veja direito os planos de Postgresql. Para aplicações médias, você provavelmente vai querer algo do tamanho do plano Standard 2, com até 400 conexões simultâneas e 3.5Gb de RAM. Na teoria, você poderia tranquilamente subir mais de 400 instâncias de Ruby (web e worker), considerando o pool de conexões. Na prática isso não deve acontecer, e isso depende muito do perfil da sua aplicação.

Especialmente considerando aplicações que precisam ou fazer queries muito complexas (relatórios, pré-cálculos que envolvam uma tabela inteira e vários joins) ou então uma aplicação onde escritas (inserts e updates) aconteçam em muito volume (uma aplicação como um Google Spreadsheet ou Twitter-like). Sempre acompanhe o dashboard do Heroku Postgresql para ver quais são os comandos mais lentos. Idealmente cada query deve estar na faixa das dezenas de milissegundos. Quando mais lenta for e quanto mais dados ele precisar carregar em memória, menos dessas você pode fazer concorrentemente no mesmo banco de dados.

Em particular, se você tem muitas tarefas pesadas, então já deveria estar usando workers de Sidekiq. Porém se lembre que esses workers estarão usando o mesmo banco que os dynos web também vão usar. Nesse caso se você rodar uma query estupidamente pesada num worker, a experiência do usuário na web vai ser prejudicada.

Update (25/11/2014): We can finally confirm that yes, the awesome Raptor project is the codename for the next release of Phusion Passenger itself! Read the announcement

If you're a seasoned Ruby web developer you're probably familiar and comfortable using the usual suspects to deploy your applications. You're either deploying something simple through good old Thin, or you're orchestrating several Ruby processes through Unicorn workers, or you're trying out JRuby and want better concurrency and thread management, and therefore you're using either Puma or Torquebox.

And even though it feels like we are already at the peak of what's possible with Ruby, we do want more. Ruby 2.1.3 was just released, 3.0 is in development. But until then it should be possible to squeeze some more performance out of your boxes.

In fact, a new contender, with some new approaches just showed up. I have little details so far, but it's a brand new product - not derived from the others - from an unknown team. This product is named "Raptor" and they claim that it can squeeze the extra juice out of our boxes.

And this is their claim:

Raptor Chart

Este ano, além da discussão sobre TDD (que não está morto!), ninguém menos que o próprio signatário do Manifesto Ágil, Dave Thomas, declarou a morte de "Ágil" como conhecemos hoje.

Alguns artigos que podem dar base ao resto da discussão:

Na minha empresa, desde sua concepção, não usamos a palavra "Ágil", "Scrum" nem nenhum buzzword. Temos sim, "sprints", mas coisas como grooming, planning poker (brincadeira!), e outros "rituais" não são de jeito nenhum "impostos", mas as práticas são usadas (com ou sem os nomes), sempre que necessárias. Não gosto de usar a palavra "Scrum", "Kanban" ou qualquer outro, me dá uma leve vergonha de mencionar esses nomes.