Strict Standards: Non-static method themeGluedIdeas_Subtle::initOptions() should not be called statically in /home/riopro/www/blog.riopro.com.br/wp-content/themes/gluedideas_subtle/header.php on line 19
Riopro Blog - » Enviando imagens para S3 assincronamente em Rails

Enviando imagens para S3 assincronamente em Rails



Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Aplicações web são processadas dentro do ciclo de requisição / resposta do protocolo HTTP. Isso significa que, por diversas razões, operações que demoram muito tempo para serem executadas não devem ser executas dentro deste ciclo, ou seja, devem ser processadas assincronamente. Isso garante uma boa esperiência de uso para o usuário, assim como evita erros de timeout, etc. Este “muito tempo” é algo subjetivo, mas em geral, se demora mais de 1 segundo, é batata: deve ser removido do cliclo requisição / resposta.

Um caso típico de processamento que deve ser assíncrono é quando sua aplicação precisa interfacear com outros sistemas (web services por exemplo). Além de todo o delay inerente em estabelecer a conexão entre os sistemas, outra razão para tornar esta operação assíncrona é a disponibilidade dos serviços, isto é, você não quer que o seu sistema fique indisponível enquanto o sistema associado estiver com problemas.

Em uma aplicação que estamos desenvolvendo, os usuários podem enviar imagens para o sistema, associando-as com outros objetos. O sistema gera vários thumbnails de cada imagem enviada, e armazena os arquivos no serviço de armazenamento de arquivos “na nuvem” da Amazon, o S3. O upload em si das imagens do computador do usuário até o servidor da aplicação não há como remover do ciclo HTTP. Porém, o envio dos arquivos para o S3 sim. Este envio normalmente é rápido, mas pode demorar vários segundos em alguns momentos. Aliás, mesmo quando é rápido, é lento demais para manter no ciclo HTTP.

Assim sendo, eis como fizemos tudo isso em uma aplicação Rails, usando os plugins attachment_fu e delayed_job.

Em tempo: o tutorial a seguir funciona com outros plugins de upload de arquivos e / ou de processamento assíncrono, basta mudar alguns detalhes específicos. Estou assumindo que você já tem experiência com upload de arquivos em Rails e pelo menos é familiar com a idéia de processamento assíncrono. Se não for o caso, leia o README dos plugins acima antes de continuar.

A idéia básica é a seguinte: quando o usuário fizer o upload de uma imagem, o sistema irá armazená-la no disco local, gerar todos os thumbnails necessários e retornar para o usuário. Em seguida, automaticamente e fora do ciclo HTTP, o sistema irá agendar um trabalho assíncrono que se encarregará de enviar as imagens (a original e todos os thumbnails) para o S3, inclusive tentando novamente várias vezes em caso de erro. O pulo do gato é que isso tudo ocorre de maneira transparente para o usuário e, mesmo enquanto a imagem não foi enviada para o S3, ela está disponível para o usuário visualizar, diretamente do disco local.

Para tal, criaremos 2 modelos de imagem, ambos utilizando a mesma tabela no banco de dados: um será das imagens “finais”, armazenadas no S3, e herdará de AR::Base; o outro será de imagens “temporárias”, armazenadas no banco de dados e herdará do modelo de imagens finais, sobrescrevendo os métodos que precisar. Eis os modelos:

Repare que a tabela “images” deve possuir, além dos campos comuns, um campo do tipo boolean de nome “temporary”, cujo valor padrão deve ser “true”.

Nas suas views e controllers, sempre que o usuário for enviar uma imagem, você deve instanciar um novo objeto TempImage (inclusive, se você tentar instanciar um novo objeto Image uma exceção será levantada). O envio assíncrono será realizado automaticamente.

Quando for exibir uma imagem ou um thumbnail, busque os registros sempre utilizando o modelo Image (mesmo que as imagens não tenham sido armazenadas no S3 ainda). Você deve utilizar o método Image#proxy_public_filename para obter o caminho para a imagem. Este método irá retornar automagicamente o caminho para a imagem no disco local (caso a imagem ainda seja “temporária”) no Amazon S3 (caso já seja “final”).

Informações e Links

Junte-se comentando, lendo o que os outros dizem ou colocando um link a partir do seu blog.


Outros Artigos

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
Alternando facilmente entre várias versões do Ruby no Ubuntu

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
Simulando chamadas Ajax para upload de arquivos

Comente

Tire um tempo para comentar e nos dizer o que você acha. Alguns códigos HTML são permitidos para formatação.

Comentários dos Leitores

Seja o primeiro a comentar!