Take advantage of assets conventions in Play

It is usual when you are working with Play use this kind of code to refer public assets.

   <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/style.css")"/>
   <script src="@routes.Assets.at("javascripts/jquery-1.4.4.min.js")" type="text/javascript">
   <img src="@routes.Assets.at("images/someimage.png"/>

But, Why do you have to write the name of css, javascript and images folder all the time if they are the convention? When you are using a framework is important to take advantage of all things, in order to avoid silly mistakes, like write the wrong name of the folder. For example, at least to me, it would be better if we could write something like this:

   <link rel="stylesheet" href="@Css("bootstrap.min.css")">
   <script type="text/javascript" src="@Js("main.js")"></script>
   <img src="@Image("someimage.png"/>

To achieve this we just have to use the built in controller named Assets. Let’s see the implementation:

  package helpers

  import controllers.routes

  object AssetsHelper {

    object Css {
	  def apply(file:String) = routes.Assets.at("stylesheets/"+file)
    }

    object Js {
	  def apply(file:String) = routes.Assets.at("javascripts/"+file)
    }

    object Image {
	  def apply(file:String) = routes.Assets.at("images/"+file)
    }

}

Now, you just have to import this class to all templates. Change your build.sbt and add this line.

   templatesImport ++= Seq("helpers.AssetsHelper._")

If you want to keep update with a lot of Play tips, follow me here and in my twitter :). Also I have my book available in Leanpub, still only in Portuguese and ASAP in English.

Play, um framework pensado para você e sua empresa

O post de hoje é para fazer você e seu time pensar em que parte da aplicação vocês querem focar no próximo projeto. Para médias e grandes aplicações, o assunto escalabilidade é realmente importante. Os sistemas precisam atender a demanda de novos clientes até o máximo que conseguir mantendo um tempo de resposta dentro do aceitável.

Para exemplificar, instalei duas aplicações que fazem exatamente a mesma coisa em uma instância da Digital Ocean para que vocês tirem as suas conclusões sobre o Play Framework.  Ambas montam uma página baseada numa consulta de banco de dados que retorna 100.000 objetos. É uma aplicação simples, que tem apenas uma classe importante que representa uma Transação Bancária.  Como implementação de pool de conexões, ambas usam o BoneCP, implementação que já vem pronta no Play e por isso usada no exemplo com Servlets. Além disso, as 2 subiram com 1gb de memória.

Aqui estão alguns números obtidos através do uso do Siege para realizer os benchmarks. Vamos olhar os números da aplicação rodando no Tomcat com o NioConnector ativado. Para não ficar nada muito impossível de se imaginar, todos os testes foram realizados simulando 100 usuários acessando a aplicação em lotes de 10. A primeira simulação, para esquentar, foi listando 1000 objetos. Abaixo os números:

  Transactions:		        100 hits
  Availability:		        100.00 %
  Elapsed time:		        6.07 secs
  Response time:		0.51 secs
  Throughput:		        0.35 MB/sec

Fique atento para a linha referente a Availability(Disponibilidade). Agora o teste mais complicado, simulando a listagem de 100000 objetos.

  Transactions:		       54 hits
  Availability:		       54.00 %
  Elapsed time:		       456.44 secs
  Response time:	       28.22 secs
  Throughput:		       0.12 MB/sec

Perceba que a disponibilidade caiu muito!. Vamos agora dar uma olhada nos números obtidos no uso do Play. Abaixo segue os números da primeira simulação com apenas 1000 objetos.

    Transactions:	         100 hits
    Availability:		 100.00 %
    Elapsed time:		 5.20 secs
    Response time:		 0.51 secs
    Throughput:		         0.38 MB/sec

Uma diferença pequena a favor do Play, mas nada que faça crescer os olhos. E agora os números obtidos a partir da segunda simulação.

    Transactions:	       100 hits
    Availability:	       100.00 %
    Elapsed time:	       195.05 secs
    Response time:	       18.45 secs
    Throughput:		       1.00 MB/sec

Nesse momento você poderia parar e olhar que todos os números foram melhores, mas eu quero que você preste atenção para a disponibilidade. Ela ficou em 100%! e é isso que sua empresa mais vai querer quando sua aplicação tiver o pico de acesso.  Com esforço zero, sem precisar fazer nenhuma configuração adicional, sua aplicação está muito mais escalável do que a outra escrita com Servlet puro, imagine se usasse algum outro framework. O tempo gasto para atender o request é um pouco alto por conta da listagem de 100.000 transações.

Caso tenha ficado curioso em relação ao código, os mesmos podem ser encontrados aqui e aqui.

A maneira mais comum de fazer isso, até por conta da facilidade encontrada hoje em dia com as ferramentas de virtualização, é criar várias máquinas e fazer o deploy da sua aplicação nessas instâncias. Eu não vou contra isso, só vou contra a ideia disso ser uma das primeiras a coisas a se pensar. Até porque, quando você opta por essa abordagem, estratégias de replicação de sessão de usuário, deploy em vários servidores e outros detalhes terão que ser pensados. E os engenheiros das grandes aplicações do mundo nunca deixam de falar que um dos fatores de sucesso é a simplicidade e não a complexidade.

Ainda foi deixado de fora, toda parte de desenvolvimento que ele facilita para você. Diferenciação de ambientes, views compiladas, integração com o Akka para  a realização de tarefas assíncronas, desenvolvimento sem pausas por conta de alterações em classes ou arquivos de configuração.

Caso tenha gostado do que o Play demonstrou, assim como o Linkedin e o Coursera, não deixe de dar uma olhada no livro que eu escrevi sobre Play e lançado pela LeanPub.