quinta-feira, 26 de janeiro de 2012

Codeigniter + Node.js + Vows.js - Notifier


Finalizando, vamos refatorar a aplicação de prova de conceito para que ela utilize utilize o servidor node.js para notificar os clientes conectados.  O código fonte final da aplicação pode ser encontrado no repositório https://github.com/fcm/codeigniter-academic

Refatorando o Worker
A classe que realiza o trabalho de redimensionamento das imagens deve ser refatorada para se conectar com o servidor node.js e assim comunicar aos seus clientes a conclusão de seu trabalho.  Vamos iniciar pelo arquivo (codeigniter-academic/spec/ResizeImageJobSpec.php) de especificação (BDD).




Manipulador de Notificações
A classe application/workers/notifier.php é responsável pela interação com o servidor node.js.  Esta classe possui um método publish que usa um client REST para  notificar seus clientes das alteração no seu estado por meio de mensagens (websocket) usando o servidor node.js (server-fayer) .



Injetando a Dependência
A classe que manipula as notificações é injetada no construtor da classe que realiza o trabalho de redimensionamento das imagens ( application/workers/resize_image_job.php). Desta maneira testar a classe ou mudar a maneira de conexão e notificação fica muito mais simples.



Rodando os testes
Rodar os testes para ver se a refatoração não quebrou nada na aplicação. O resultado deve ser próximo da figura abaixo.




Rodando a Aplicação
Sempre que um worker finaliza um trabalho de redimensionamento das imagens ele se conecta por meio do protocolo HTTP usando o cliente REST com o servidor Node.js que publica esta mensagem para os clientes conectados num determinado canal. Desta forma não é necessário que todos os clientes façam Long Polling para descobrir o se as imagens já foram redimensionadas. Isso ajuda muito a escalar uma aplicação web diminuindo o número de requisições.

Foi criado um segundo canal por onde podem ser enviadas mensagens gerais para a aplicação. Pode ser usado a aplicação Curl para testar a funcionalidade direto do terminal conforme o comando da imagem abaixo.




REFERÊNCIAS
http://howtonode.org/how-to-module
http://www.adityaravishankar.com/2011/10/nowjs-node-js-tutorial-creating-multi-room-chat-server/
http://simas.posterous.com/writing-a-php-daemon-application
http://www.lifeyun.com/node-js-building-for-scalability-with-server-side-javascript.html
http://www.vivaolinux.com.br/artigo/Node.js-para-administradores-de-sistema
http://vowsjs.org

sexta-feira, 30 de dezembro de 2011

Codeigniter + Node.js + Vows.js


Continuando o post anterior iniciaremos o desenvolvimento da aplicação Node.js que notificará os clientes assim que os jobs de redimensionamento das imagens forem finalizados.

Asynchronous BDD com Vows.

Com todas as bibliotecas já instaladas e configuradas o primeiro passo é desenvolver os scrips da aplicação e como não poderia deixar de ser vamos iniciar pelos testes que guiarão o desenvolvimento.  Vamos utilizar a biblioteca de BDD Vows e para mais informações de como instalar o módulo acesse o site do projeto em: http://vowsjs.org.


Criar o arquivo application/servers/spec/server-now-test.js





Criar o servidor node
Criar o arquivo /home/fabrizio/public_html/dev.localhost/codeigniter-academic/application/servers/server-now.js para iniciar o desenvolvimento da aplicação Node.js



Iniciar a aplicação Node.js e rodar os testes.
$ node application/servers/server-now.js 
$ vows application/servers/spec/server-now-test.js --spec

A saída deve ser como a imagem abaixo.


Middleware
Como pode ser observado na aplicação Node.js foi inserido um middleware que intercepta a requisição e verifica se o cliente que está solicitando o serviço tem autorização.  Para isso foi criado um módulo de autenticação básica que não permite que os clientes sem permissão possam enviar mensagens aqueles clientes conectados na aplicação.

Um middleware pode ser inserido na cadeia de outros serviços que recebem, tratam e repassam a requisição, desta forma este middleware vai recuperar o header, verificar se o usuario e senha são válidos, e passar para frente a requisição.
var server = express.createServer();
server.configure(function () {
server.use(express.logger());
server.use(auth.basicAuth);
server.use(express.bodyParser()); 
server.use(express.static(__dirname + '/public'));
});


Modulo de Autenticação
Criar um módulo para o Node.js é muito simples.  Vamos criar o diretório application/servers/node_modules/basic-auth e nele criar o arquivo application/servers/node_modules/basic-auth/package.json
que vai descrever o novo módulo.


Criar o script application/servers/node_modules/basic-auth/basic-auth.js para desenvolver uma autenticação http básica.  Esta é uma funcionalidade muito simples, mas que pode ser refatorada para tornar o acesso ao servidor mais seguro. Mas para efeito didático, por hora é o suficiente. Baseou-se no script disponível em https://github.com/dawnerd/node-basic-auth




Administrando Serviços no Ubuntu
Vamos configurar aplicações facilitadoras na administração dos serviços que necessitam rodar em background, assim como manipular os arquivos de log da nossa aplicação Node.js.


Processo do Node.js como um Daemon 
Upstart é o init daemon default que o Ubuntu  utiliza para rodar processos em background. Com ele é possível levantar os processos da aplicação Node.js em background. Conheça mais no wiki do projeto http://wiki.ubuntu-br.org/Upstart.

Criar o arquivo /etc/init/node-resize.conf com as configurações e o caminho do script do nosso serviço Node.js


Agora basta dar permissão de execução ao arquivo e já é possível iniciar, parar e administrar o processo de forma simples com o uso do Upstart.
$ sudo chmod +x /etc/init.d/node-resize.conf
$ status nodetcp
$ sudo start nodetcp
$ sudo stop nodetcp
$ initctl help
$ initctl list | grep nodetcp
$ netstat -tnlp


Manipulando os arquivos de  Logs
O Logrotate do Ubuntu (http://manpages.ubuntu.com/logrotate) facilita a adminstração dos arquivos de logs permitindo dividir e rotacionar grandes arquivos.

Criar o arquivo /etc/logrotate.d/node-server para configurar como o log será rotacionado.
/var/log/node-resize.log {
 weekly;
 rotate 4;
}


Finalizando
Agora é só levantar a aplicação Node.js com o Upstart e rodar os testes para verificar se todos passam.
No próximo post vamos refatorar o Job do Worker de redimensionamento das imagens para que ele utilize esta aplicação Node.js para notificar o término de sua tarefa.
$ sudo start node-resize 
$ vows application/servers/spec/server-now-test.js --spec


REFERÊNCIAS
http://howtonode.org/how-to-module
http://www.adityaravishankar.com/2011/10/nowjs-node-js-tutorial-creating-multi-room-chat-server/
http://simas.posterous.com/writing-a-php-daemon-application
http://vowsjs.org/#installing
http://www.lifeyun.com/node-js-building-for-scalability-with-server-side-javascript.html
http://www.vivaolinux.com.br/artigo/Node.js-para-administradores-de-sistema
http://vowsjs.org

domingo, 11 de dezembro de 2011

Codeigniter + node.js + now.js + express


Aplicações Híbridas - Php + node.JS

Usualmente uma prática comum é integrar aplicações php, ruby e etc com aplicações node.JS, aproveitando assim as facilidades das bibliotecas do Node na construção de aplicações real-time e utilização de websocket.

Vamos modificar a feature de upload da aplicação utilizando o node.JS para possibilitar que os navegadores sejam notificados pelo servidor a cada nova imagem redimensionada, sem a necessidade de uma nova requisição ao servidor para saber se o trabalho já foi realizado.
Assim a aplicação php vai usar o serviço node para transmitir a mensagem aos clientes inscritos em determinados canais.

fonte: http://www.lifeyun.com


Instalar o Node.js no ubuntu
Node.js, framework serve-side javascript que utiliza o motor V8 do Chrome e que facilita muito escalar aplicações web principalmente usado em funcionalidades real-time onde é necessário comunicação assíncrona e suporte a um grande número de requisições.

$ sudo apt-get install g++ curl libssl-dev apache2-utils
$ sudo apt-get install git-core
$ git clone https://github.com/joyent/node.git
$ cd node
$ ./configure
$ make
$ sudo make install
$ node --version


Instalar o gerenciador de pacotes NPM
O npm (http://npmjs.org) é o gerenciador de pacotes padrão do node. Facilita o gerenciamento de módulos e depêncencias do projeto.  Existem diversos módulos prontos para auxiliar no desenvolvimentos de apps node que podem ser consultados no wiki do projeto em https://github.com/joyent/node/wiki/modules

$ curl http://npmjs.org/install.sh | sudo sh 

Instalar o Now.js
O NowJS (http://nowjs.com/) é um framework que encapsula as funcionalidades do socket.io e sobe o nível, facilitando e deixando mais transparente a construção de aplicações pub/sub.  Você pode fazer seus clientes facilmente invocar funções do servidor ou seu servidor chamar funções dos clientes conectados. Facilita também agrupar clientes em um ou multiplos grupos.
$ mkdir codeigniter-aceademic/application/servers
$ sudo npm install now

Instalar o plugin Jquery.Notify

Um plugin jQueryUI para criar um widget de notificação como o Growl do Mac ou o Ubuntu Notification do Ubuntu. Vai servir para apresentar as mensagens que estão sendo transmitidas via websocket do servidor para os clientes. Mais informações sobre a instalação ver o site do plugin em http://www.erichynds.com/jquery/a-jquery-ui-growl-ubuntu-notification-widget



Copiar os arquivos do plugin para
assets/js/libs/jquery.notify.min.js
assets/js/libs/jquery-ui-1.8.16.custom.min.js
assets/css/libs/ui.notify.css
assets/css/libs/jquery-ui-1.8.16.custom.css

Incluir os scrips no arquivo application/core/MY_Controller.php


Refatorar as views para usar o Jquery.Notify

Criar uma partial em application/views/layout/_notify.php para encapsular os templates que o plugin notify utiliza para apresentar as mensagens na aplicação.


Referenciar a partial no template global da aplicação application/view/layout/application.php



Javascript client

Criar o script assets/js/application.js para inscrever (subscribe) a aplicação em dois canais distintos e ficar escutando qualquer mensagem enviado pelo servidor. Um canal recebe mensagens quando o worker terminar de redimensionar a imagem e outro que recebe mensagens gerais sobre o sistema.



Biblioteca rest-client
Para acessar o servidor node vamos utilizar uma biblioteca REST para o codeigniter que faclita as chamadas e manipulação dos métodos httpd necessários para se comunicar com os serviços públicos da api da aplicação node que será construida utilizando o módulo Express. Mais informações sobre a instalação podem ser acessadas no site https://github.com/philsturgeon/codeigniter-restclient
$ php tools/spark install -v2.0.0 restclient


Referências
http://howtonode.org/how-to-module
http://www.adityaravishankar.com/2011/10/nowjs-node-js-tutorial-creating-multi-room-chat-server/
http://vowsjs.org/#installing
http://www.lifeyun.com/node-js-building-for-scalability-with-server-side-javascript.html
http://www.vivaolinux.com.br/artigo/Node.js-para-administradores-de-sistema

segunda-feira, 5 de dezembro de 2011

Codeigniter 2 + Backgroud Job + Gearman


Dando continuidade ao post anterior vamos criar uma nova funcionalidade no sistema para validar o funcionamento do Gearman.  Vamos criar uma página para upload de imagens que delega a tarefa de criar as imagens de thumbs para o worker realizar em background. Dessa forma o cliente fica livre para executar outras tarefas enquanto aguarda o worker do Gearman finalizar os trabalhos colocados na fila.


Feature de Upload

Criar o controller application/controllers/jobs.php que controla a interface de upload e que delega o trabalho para o worker processar em background.


Criar as views e partials que compõe a interface html para fazer o upload e listagem das imagens
application/views/jobs/index.php


application/views/jobs/_photo.php


application/views/jobs/_form_upload.php



Resultado Final
Após o upload de uma imagem a aplicação redireciona para a mesma página que lista as imagens do diretório e libera o navegador.  O processo de redimensionamento das imagesn é enviado para a lista de jobs do Gearman e realizada pelos workers de forma assíncrona.


Para visualizar as imagens que já foram redimensionadas basta fazer um reload da página.




Referências:
http://gearman.org/
http://www.phpclasses.org/blog/post/108-Distributing-PHP-processing-with-Gearman.html
http://imasters.com.br/artigo/21385/php/processamento-distribuido-em-php-utilizando-gearman-parte-1
http://pecl.php.net/package/gearman

quinta-feira, 17 de novembro de 2011

Codeigniter 2 + Gearman + Phpspec


PhpSpec?
Framework de BDD (Behavior-Driven Development) para o desenvolvimento e design de aplicações php orientadas por comportamento.  Para conhecer melhor BDD leia o artigo  http://www.urubatan.com.br/comparacao-entre-tdd-e-bdd-como-aprender-um-me-ajudou-com-o-outro/  do blog do Urubatan que é a fonte da imagem.



Instalar PhpSpec
O pacote do phpspec pode ser instalado pelo pear
$ sudo pear config-set preferred_state beta
$ sudo pear channel-discover pear.phpspec.net
$ sudo pear install --all-deps phpspec/PHPSpec

Criar estrutura inicial
Criar o diretório spec na rais do projeto com a seguinte estrutura para acomodar os arquivos de especificação.



Bootstrap da stack do Codeigniter
Criar o arquivo codeigniter-academic/spec/spec_helper.php que será importado a cada nova spec. A primeira linha do código inclui a stack do codeigniter utilizando o mesmo bootstrap customizado do CIUnit, isso possibilita a uitilização de qualquer bibliotecas do framework.

photo.png
Fixture
Copiar uma imagem-fixture qualquer no diretório
codeigniter-academic/spec/fixtures/photo.png para validar os testes e verificar se a classe ResizeImageJob faz corretamente o redimensionamento de uma imagem.

Após cada exemplo de teste a classe de especificação deve limpar as imagens thumbs geradas para que não inflencie nos demais exemplos.


Refatorar o worker 
O worker feito no post anterior foi refatorado para reutilizar as bibliotecas de manipulação de imagem do próprio Codeiginiter. Esta refatoração foi orientada por BDD com o uso do framework PhpSpec.

A classe ResizeImageJob:
 - Cria novas imagens de thumbs a partir da original
 - Preserva a imagem original
 - Permite desfazer a tarefa executada
 - Lança uma exception caso não receba um array com parametros

Criar o arquivo da especificação em codeigniter-academic/spec/ResizeImageJobSpec.php. 

O código é bem simples, antes de cada exemplo é criado um array com parâmetros com o path para a imagem de fixture, um array com a especificação dos tamanhos dos novos thumbs a serem criados além de outros. Os dois métodos privados server apenas como auxiliares para diminuir a repetição de código e deixá-lo mais DRY.

Extrair a classe responsável pela tarefa 
O código do worker (application/workers/resize_worker.php) do post anterior anterior possui mais de uma responsabilidade. Além de administrar o serviço do worker ele ainda manipula as imagens.  O objetivo é extrair a responsabilidade de redimensionar as imagens para uma nova classe de job.

A nova classe application/workers/resize_image_job.php encapsula a única responsabilidade de redimensionar as imagens.  Ela segue um pouco o design pattern command, recebendo parametros no construtor e executando a tarefa de sua responsabilidade no método execute(). Também possui um método undo() que reotrnar o estado antes da execução da sua tarefa.

Refatorar o script de inicialização do worker
Agora o scrip que inicializa o worker tem somente esta responsabilidade e a tarefa que o worker realiza pode ser feita alterando a classe ResizeImageJob sem a necessidade de parar e reiniciar o worker.  O script refatorado application/workers/resize_image_worker.php

Convenção nos nomes de arquivo
Para facilitar a manutenção dos workers e o carregamento automático das classes de jobs do projeto foi criado um helper que carrega a classe de job de mesmo prefixo do arquivo worker inicializado. Assim um arquivo worker resize_image_worker.php inclui sua classe job resize_image_job.phpO arquivo application/workers/worker_helper.php deve ser incluido na primeira linha de cada novo worker.

Rodando a suite de specs
Rodar as specs a partir do diretório raiz do projeto
(gearman) $ phpspec spec/ --formatter documentation --color
O resultado deve ser o mesmo da próxima a imagem afirmando que todos os exemplos da specificação definida no início da refatoração estão passado (green).


Referências:
http://www.phpspec.net
http://www.slideshare.net/marcello.duarte/phpspec-bdd-for-php
http://techportal.ibuildings.com/2011/07/21/outside-in-behaviour-driven-development-in-php
http://techportal.ibuildings.com/2011/08/03/outside-in-behaviour-driven-development-in-php-part-2
http://www.urubatan.com.br/comparacao-entre-tdd-e-bdd-como-aprender-um-me-ajudou-com-o-outro/

segunda-feira, 14 de novembro de 2011

Codeigniter 2 + Background Job + Gearman


Continuando o post anterior vamos criar os scripts para administrar o servidor Gearman e seus workers e instalar e configurar o Monit para monitorará-los. Os fontes podem ser emcontrados no repositório público do projeto em https://github.com/fcm/codeigniter-academic/tree/gearman

Iniciar e parar os workers
Criar o arquivo /etc/init.d/gearman-workers com o conteúdo abaixo.  Mais tarde o correto é refatorar o script para obter um path relativo ao worker, mas por hora isso é o suficiente.

Criar o arquivo /etc/init.d/pskiller.sh com o conteúdo abaixo que foi adaptado do script disponível em http://www.vivaolinux.com.br/script/pskiller

Agora é possível iniciar ou parar determinados workers pelo console. Depois de iniciar os workers é possível vizualizar no monitor (http://localhost/gearman-monitor/) os 5 workers registrados para atender as solcitações.
$ sudo /etc/init.d/gearman-job-server start
$ sudo /etc/init.d/gearman-workers start resize_worker.php # para iniciar 5 workers
$ sudo /etc/init.d/gearman-workers stop resize_worker.php # para parar todos

Instalar e configurar o Monit
O Monit serve para monitorar os serviços de um ou mais servidores, ele pode ser configurado para enviar notificações e/ou tomar alguma decisão assim que um serviço ficar fora do ar ou seu consumo chegar a um determinado nível crítico.

Para instalar no Ubuntu digite na linha de comando:
$ sudo apt-get install monit
Criar um arquivo de configuração de monitoramento
$ sudo vi /etc/monit/conf.d/gearman.conf
Incluir o conteúdo no arquivo /etc/monit/conf.d/gearman.conf
check process gearmand with pidfile /var/run/gearman/gearmand.pid
   start program = "/etc/init.d/gearman-job-server start; /etc/init.d/gearman-workers stop"
   stop program = "/etc/init.d/gearman-job-server stop"
   group gearman

Alterar as configurações gerias em /etc/monit/conf.d/general.conf
set alert fabrizio.machado@gmail.com
set alert fabrizio@gmail.com
set mailserver smtp.gmail.com port 587
        username "fabrizio@gmail.com" password "xxxxxx"
        using tlsv1
        with timeout 30 seconds
set daemon 60
set logfile /var/log/monit.log

Interface web de monitoramento
O Monit possui uma interface web de monitoramento disponível por padrão em http://localhost:6874/  com o usuário e senha de acesso admin e monit

É possível alterar as configurações de portas e login descomentando o bloco referente as configurações de acesso no arquivo /etc/monit/monitrc.
## Monit has an embedded web server which can be used to view status of 
## services monitored and manage services from a web interface. See the
## Monit Wiki if you want to enable SSL for the web server. 
#
# set httpd port 2812 and
#     use address localhost  # only accept connection from localhost
#     allow localhost        # allow localhost to connect to the server and
#     allow admin:monit      # require user 'admin' with password 'monit'
#     allow @monit           # allow users of group 'monit' to connect (rw)
#     allow @users readonly  # allow users of group 'users' to connect 

Referências:
http://gearman.org/
http://mmonit.com/
http://www.phpclasses.org/blog/post/108-Distributing-PHP-processing-with-Gearman.html
http://imasters.com.br/artigo/21385/php/processamento-distribuido-em-php-utilizando-gearman-parte-1
http://pecl.php.net/package/gearman

quinta-feira, 10 de novembro de 2011

Codeigniter 2 + Background Job + Gearman


O Gearman distribui o processamento de tarefas em vários workers, permite executar tarefas em paralelo e até mesmo tarefas em hosts separados.  É possível trabalhar com tarefas síncronas ou assíncronas usando uma fila de jobs que pode ser persistente ou armazenada em memória.



Instalando Gearman no Ubuntu
Instalar o pacote via apt-get
$ sudo apt-get install gearman-job-server
Incluir as linhas no arquivo /etc/default/gearman-job-server para persistir a fila de tarefas.
# Parameters to pass to gearmand.
PARAMS="--listen=127.0.0.1 -q libsqlite3 --libsqlite3-db=/tmp/gearman.sqlite"
Reiniciar o serviço com as novas configurações:
$ sudo /etc/init.d/gearman-job-server restart
Para consultar a lista de tarefas pendentes na fila:
$ sqlite3 /tmp/gearman.sqlite
sqlite> select * from gearman_queue;

Configurando o Gearman-Monitor
Baixar os arquivos do projeto em https://github.com/yugene/Gearman-Monitor no  diretório público do servidor http.  As configurações podem ser modificadas no arquivo /var/www/gearman-monitor/_config.php

É possivel monitorar os servidores disponíveis, a quantidade de workers registrados a quantidade de jobs rodando e aguardando na fila.


Configurando extensão PHP
Instalar o pacote pelo pecl http://pecl.php.net/package/gearman
$ sudo pecl install gearman

Configurando a Lib Gearman no Codeigniter

Basta copiar os arquivos e configurar conforme as instruções do link http://codeigniter.com/wiki/Gearman


Criando o Worker
A idéia é que o redimensionamento das imagens não trave a navegação do cliente.  De maneira assíncrona o worker redimensiona a  imagem para todos os tamanhos necessários e quando concluído envia um email para o cliente ou até poderia atualizar as imagens em real-time com o uso de alguma tecnologia de pushing com websockets.

Criar o arquivo application/workers/resize_worker.php com o conteúdo abaixo.  Este é o worker que recebe e realizar o trabalho de redimensionar as imagens em background.

Para iniciar o worker basta executar o script php.  Depois é possível observar no Gearman-Monitor este worker registrado e aguardando a solicitação dos clientes.
$ sudo php <app>/application/workers/resize_worker.php

Continuação:
Nos próximos posts continuarei com a configuração dos serviços de monitoramento e scripts para administração do Gearman usando o Monit e também como integrar melhor os workers com a stack do Codeigniter para reutilizar as bibliotecas padrões do framework.

Referências:
http://gearman.org/
http://www.phpclasses.org/blog/post/108-Distributing-PHP-processing-with-Gearman.html
http://imasters.com.br/artigo/21385/php/processamento-distribuido-em-php-utilizando-gearman-parte-1
http://pecl.php.net/package/gearman