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.

Hoje eu li uma série de tweets de Marc Andressen onde ele começa dizendo o seguinte:

"Faça o que ama"/"Siga sua paixão" é um conselho perigoso e pode destruir sua carreira.

Outra celebridade reconhecida nos EUA é Mark Cuban, dono do Dallas Mavericks que, em 2012, disse a mesma coisa:

"Não siga sua paixão, siga seu esforço."

Ao que indica, o famoso Confucious disse pela primeira vez a frase que se tornaria um dos maiores clichês para jovens, saindo da adolescência e tendo que encarar a vida adulta de responsabilidades reais:

"Faça o que você ama e o dinheiro vem em seguida."

Aliás, Confucious é meio que um genérico pra tudo: não sabe quem disse? Diga que é de Confucius. (Aliás, o disclaimer de sempre: só porque eu citei pessoas não significa que concordo com elas ou com tudo que dizem, são meras referências!)

Nunca imaginei que fosse chegar a este ponto e - juro que não foi planejado - coincidiu com o último dia da 7a Rubyconf Brasil, e com o 10o aniversário do Ruby on Rails!

Além disso coincidiu com a primeira palestra que farei numa Rubyconf Brasil desde 2010.

A Palestra mais importante que dei até hoje

Muitos dizem que não acreditam em coincidências, eu por outro lado, acredito em providência. Alguém se lembra do que escrevi no meu Primeiro Post, em 2006?

E recentemente nosso grande camarada Rafael Rosa Fu do GrokPodcast - que aliás, também lançou o último episódio da minha conversa com George Guimarães, Carlos Brando sobre os 10 anos de Ruby on Rails - começou uma iniciativa no Twitter com a hashtag #ClubeDosPosts. Tantos grandes e talentosos desenvolvedores despontaram nos últimos 8 anos de Rails no Brasil e gostaríamos muito que eles compartilhassem seu conhecimento e experiência com todos nós. Ajude-nos a incentivá-los!

Diferente do que eu faria, desta vez resolvi escrever pouco e pela primeira vez também no meu blog, pedi ao Rafael Rosa para escrever em suas palavras sobre este assunto. Assim, o resto do artigo são as palavras não alteradas do Rafael.

Obrigado a todos por me acompanharem por tanto tempo, espero chegar no post 10.000 um dia!

Eu expliquei rapidamente sobre Metasploit no artigo anterior, e sobre o desafio do @joernchen. Se você ainda não resolveu o desafio, talvez queira deixar pra ler este artigo depois!

SPOILER ALERT

Mas se abriu até aqui no artigo é porque quer saber o que é o problema. O @joernchen publicou exatamente o seguinte código:

Ontem o @joernchen mandou um pequeno desafio básico de segurança pra comunidade. Ele postou um código de uma pequena aplicação, colocou ela no ar, e nos desafiou a resetar a senha do administrador.

Confesso que demorei mais do que gostaria mas no fim eu consegui - e foi simples (post sobre isso vem depois).

No caminho eu acabei explorando o Metasploit, provavelmente um dos melhores e mais conhecidos pacotes de testes de penetração de segurança. E alguns não sabem disso mas ele não só é código-aberto (existem ferramentas e serviços pagos) como é uma aplicação Rails! Então vale muito a pena acompanhar esse projeto.

Finalmente consegui fazer uma retrospectiva com os principais acontecimentos não só da última década de Ruby on Rails mas eventos em anos anteriores e durante que influenciaram nosso ecossistema de alguma forma significativa.

Como base eu pedi permissão ao Luke Francl que publicou o artigo original Looking Backward: Ten Years on Rails. Sobre ele, adicionei diversas novas datas que não estavam lá mas que foram significativas.

Certamente tem diversos outros que eu não coloquei ou me esqueci mesmo (vou adicionando aos poucos). Se quiserem contribuir eu coloquei um Gist para que todos possam fazer fork e me mandar mudanças.

Quando vocês começaram a programar com Rails/Ruby e por que? Coloque nos comentários abaixo! Eu devo fazer um outro post separado também contando um pouco do meu começo com Rails mais pra frente.

Este vai ser curto (finalmente!), tenho alguns links que estão abertos como abas no meu browser faz muito tempo, hora de colocar no post para poder fechá-los.

Já se perguntou onde encontrar or projetos que o pessoal open source está mexendo mais ultimamente?

Se não conhecia, um lugar que você pode ir é o Ruby Toolbox. Ali você pode procurar sobre algum assunto, por exemplo, parsing de JSON e lá você pode descobrir que tem o multi_json (que no fundo é um adaptador pro demais) e que a gem "js...

TL;DR: This is the Google Maps with all the places I mention in this post already set up in layers over the city.

All Tourism Points in São Paulo

If you read my mini City Guide from last year you're probably already acquainted with the Geography of the place. It's always important to be aware of your surroundings when you're in a foreign land.

Now you're here, you don't have a lot of time to randomly explore. And that would not be efficient anyway because São Paulo is humongous in size. I live here all my life, almost 4 decades, and I didn't explore everything yet.

São Paulo Aerial

But if you're near a Subway station (Metro) you're in luck as many of the staples of the city are at walking distance from the many stations or not far with Taxi from one of the stations. So let me pinpoint a few must-go places.