Você está na página 1de 5

Programao Orientada a Eventos no lado do

servidor utilizando Node.js


Francisco de Assis Ribeiro J unior (fjunior87@gmail.com/francisco.ribeiro@ifactory.com.br)
Ifactory Solutions, Fortaleza -CE


Resumo A disponibilizao de sistemas atravs da WEB
trouxe a tona uma problemtica no existente anteriormente:
como escalar sistemas com milhares, ou at milhes de usurios
simultneos. O modelo baseado em threads se mostra ineficiente
em situaes onde h vrias solicitaes simultneas. Com isso,
um modelo baseado em eventos tem se mostrado mais eficiente
para situaes onde h vrias solicitaes simultneas e grande
demanda por operaes de I/O. Node.js um framework que foi
construdo com o intuito de facilitar a construo de sistemas
orientados a eventos, altamente escalveis e com alto
desempenho. O presente trabalho pretende mostrar conceitos de
programao orientada a eventos, bem como mostrar a
utilizao do Node.js como ferramenta para tal modelo de
programao.

Palavras-chave Node.js, Programao Orientada a Eventos,
Assncrono.

Abstract When the systems were made available through
the WEB raised a kind of problem that was not experienced
before, how to scale systems with thousand or even million
concurrent users. The thread based model has been shown
inefficient in situations where there are too many concurrent
requests. Because of that, the event based model has been shown
more efficient in situations where there are many concurrent
requests and a high demand for I/O operations. Node.js is a
framework that was built in order to make easy the building of
high scalable and performatic event-driven systems. This article
intends to present some concepts of event driven programming
and to present the use of Node.js as tool for using this
programming model.

Keywords Node.js, Event-Driven Programming,
asynchronous.


I. INTRODUO

Nos dias atuais, a Internet umdos principais meios para
disponibilizao de dados, produtos, servios, entre outros.
Alm de trazer um nmero imenso de possibilidades de
sistemas que podem ser desenvolvidos e disponibilizados
atravs dela, a Internet, tambm traz grandes desafios na
construo dos mesmos. Entre os principais desafios
enfrentados nos sistemas voltados para Internet a
escalabilidade: como manter o sistema com umbom tempo
de resposta, robusto e disponvel, mesmo com uma alta
demanda de milhes ou bilhes de usurios simultneos[1].
Welsh at. al [1] mencionamque o aumento no nmero de
acessos resulta numaumento nas operaes que envolvem
Input/Output e requisies a recursos disponibilizados atravs
de uma rede.
A medida que a complexidade e o nmero de conexes
simultneas crescem, h a necessidade de utilizao de
diferentes tcnicas para se alcanar a escalabilidade
necessria.
Kegel [2] descreve o C10k problem no qual menciona
que o limite de conexes simultneas suportadas pela maioria
dos web servers de 10.000 (dez mil). Alm disso, menciona
que para suportar a mencionada quantidade de conexes
simultneas, o hardware no o nico gargalo, mas que tal
poderia ser alcanado atravs da mudana no modo em que
as operaes de I/O so realizadas.
Muitos softwares se utilizam do modelo de threads para
alcanar concorrncia de I/O e outros recursos. Um dos
principais aspectos que fazem do uso de threads a escolha
inicial quando fala-se de concorrncia a preservao da
aparncia de programao serial [3]. Um outro aspecto
importante que leva ao uso de threads, a capacidade de
utilizao de multiprocessadores ou cores [4].
Segundo Welsh at. al[1], embora haja um certo grau de
facilidade no desenvolvimento de aplicativos baseados em
thread, muito por conta da adoo das mesmas emboa parte
das linguagens de programao, o overhead associado as
threads pode levar a uma degradao do desempenho
medida emque o nmero de threads aumenta. Isso se d
devido ao fato de que nesse modelo, cada requisio
atendida por uma thread separada, ou seja, quanto maior o
nmero de conexes simultneas, maior ser o nmero de
threads abertas.
Devido aos limites de escalabilidade impostos pelo
modelo baseado em threads, muitos desenvolvedores tm
optado por ummodelo baseado em eventos para gerenciar
concorrncia [1].
H vrios sistemas desenvolvidos utilizando ummodelo
baseado em eventos, entre os quais possvel citar: Nginx
[5], G- Wan [6] web servers. H tambmferramentas que
podem ser utilizadas para criao de sistemas baseados em
eventos, entre os quais possvel citar: Python Twisted [7] e
o Ruby Event Machine [8].
O presente trabalho ir apresentar conceitos de
programao orientada a eventos, e utilizar como ferramenta
o Node.js [9], o qual ser descrito nas sees subseqentes.




II. PROGRAMAO ORIENTADA A EVENTOS

Em sistemas web convencionais, o modelo padro
utilizado o Request-Response. Umcomponente cliente faz
uma requisio (request) a um componente servidor ou
provider, que recebe a requisio e produz uma resposta
(response).
Em contrapartida, em programas construdos utilizando
um paradigma orientado a eventos, tudo gira em torno de
eventos. Evento uma indicao de algo que aconteceu,
consequentemente a terminologia utilizada para os
participantes muda, agora existe o produtor do evento (event
producer) e o consumidor do evento (event consumer) [10].
Uma das principais diferenas encontradas emsistemas
baseados em eventos, que em geral, o cliente (event
producer) no espera pela ao a ser executada pelo servidor
(event consumer) [1], ou seja, trata-se de uma interao non-
blocking, pode-se at dizer assncrona.
possvel exemplificar essa diferena com a seguinte
situao: em programas sncronos, ao ser feita uma requisio
em um banco de dados h a necessidade de esperar a
requisio ser completada para ento processar os resultados.
J em um programa assncrono, ao ser feita uma requisio a
um banco de dados, ser especificado o que deve ser feito
com os resultados da requisio. O programa no espera a
finalizao da requisio, e passa para outras atividades. E
apenas quando o resultado retornado, a lgica de
manipulao dos resultados que foi especificado no momento
da requisio executada [11]. A essa lgica que executada
aps a finalizao da requisio d-se o nome de callback.
Umexemplo de chamada assncrona e a especificao de
umcallback pode ser visto na Figura 1.


Figura 1. Exemplo de chamada assncrona e callback

Na Figura 1, possvel ver uma chamada a funo getData,
esta funo recebe dois parmetros: uma instruo SQL a ser
executada, e uma funo de callback. Esta funo de callback
que ser executado no momento da finalizao da consulta
SQL. O ponto principal que a chamada da funo getData,
no bloqueia a execuo do restante do cdigo, ou seja, a
chamada da funo readFromFile no ir esperar at a
finalizao da chamada de getData.
Diferente de programas baseados emthreads, geralmente
programas orientados a eventos, consistemde um nico loop,
chamado de event loop, que espera por eventos, e repassa os
mesmos para o manipulador do evento. Programas baseados
em eventos executam os callbacks serialmente, por esse
motivo, no h preocupao com controle de concorrncia
[4]. Dabek at. AL [4] mencionamque por se tratar de uma
nico loop, programas baseados em eventos no usufruemde
multiprocessamento ou cores, e para tal se faz necessrio a
execuo de cpias do mesmo aplicativo.
Programao orientada a eventos algo bemnatural em
aplicativos no lado do cliente (client-side), como por exemplo
interfaces grficas, nas quais programam-se quais as aes
devero ser realizadas aps a ocorrncia de algumevento,
tais como clique em botes, redimensionamento de uma
janela, dentre outros. Isto tambm algo bemnatural no
desenvolvimento web, onde eventos como onclick, onload,
dentre outros so bastante comuns.
Por outro lado, este no umparadigma to natural no
lado do servidor (Server-side), por no lidar com as
interaes do usurio com os componentes da interface
grfica. Com isso, h a necessidade de aplicao de tcnicas
de programao diferentes das usadas quando se desenvolve
de forma serial. Sendo isto, um dos principais aspectos
negativos mencionados a respeito deste paradigma de
programao [4].
Por se tratar de comunicao assncrona, muito dos
padres descritos por Hohpe e Woolf [12] podem ser
aplicados emprogramao orientada a eventos.

III. NODE.JS

Node.js uma plataforma cujo objetivo a fcil
construo de rpidas e escalveis aplicaes de rede. Para tal
emprega ummodelo baseado em eventos, e non-blocking I/O
[9]. Foi desenvolvido por Ryan Dahl em2009. Trata-se de
um ambiente javascript no lado do servidor, single-threaded,
implementado emC/C++ [13].
Aplicaes Node.js podem ser escritas utilizando
javascript, para tal, o framework faz uso da Javascript
Engine V8 do Google [14]. A V8 a implementao
javascript utilizada pelo navegador Google Chrome,
extremamente rpida, mas necessitou de algumas
modificaes para que tenha ummelhor funcionamento em
outros contextos que no sejamo browser [15]. Para que se
tenha I/O baseado em eventos e non-blocking, o Node.js faz
uso de bibliotecas C libev [16] e libeio [17], desenvolvidas
por Marc Lehmann.
O Node.js composto por diversos mdulos: mdulos que
fazem parte do ncleo da plataforma, chamados core
modules, e mdulos desenvolvidos pela comunidade. A
arquitetura padro da plataforma pode ser vista na Figura 2.


Figura 2. Arquitetura Node.js [9]

O projeto Node.js teve influncia de outros sistemas como
o Python Twisted e o Ruby Event Machine. Uma das partes
fundamentais da arquitetura Node.js o Event Loop. O event
loop o mtodo que o javascript utiliza para lidar comos
eventos de uma melhor maneira [15]. O Event Loop permite
que o framework, ao invs do sistema operacional, gerencie a
mudana entre as tarefas a seremexecutadas [11]. Para o
event loop o Node.js se utiliza da biblioteca libev.
A Figura 3. mostra umexemplo bsico mostrado no site
do Node.js, onde h a criao de um simples Web Server.



Figura 3. Web server feito com node.js

No cdigo mostrado na Figura 3, utilizado um dos
mdulos padro do Node.js, o mdulo http, que possui uma
funo para a criao do servidor. Esta funo recebe como
parmetro uma outra funo, esta a funo de callback que
ser executada a cada requisio feita ao Web Server. A
resposta dessa requisio ser basicamente a exibio da
mensagemHello World.
Atravs deste exemplo, pode ser visto um dos principais
motivos da escolha do javascript como linguagem utilizada,
seu suporte a callbacks de eventos [13]. Isto se d, pelo fato
de que em javascript funes so first-class objects, isso
significa, que podem ser utilizadas como parmetros em
outras funes, como retorno de uma funo, e atribudas a
variveis [11]. Alm disso, h a possibilidade de criao de
funes annimas, o que d grande flexibilidade na criao
de callbacks.
possvel observar a natureza assncrona da API do
Node.js atravs do exemplo mostrado na Figura 4.


Figura 4. Exemplo de chamada assncrona no Node.js

Ao executar o cdigo mostrado na Figura 4. a sada gerada
no console pode ser vista na Figura 5.


Figura 5. Sada gerada pela execuo do cdigo de
exemplo

Atravs da sada gerada no console, percebe-se a natureza
non-blocking da API Node.js. A sada After path.exists no
esperou a chamada a path.exists finalizar para ser executada,
ou seja, a execuo da aplicao no ficou bloqueada.





IV. EVENTOS COM NODE.JS

Umdos principais aspectos do Node.js a questo do
tratamento de eventos, ou seja, produo e consumo dos
eventos. O framework prov um mdulo especfico para
tratamento de eventos, o mdulo events. Este mdulo
disponibiliza uma classe genrica para manipulao de
eventos, a classe EventEmitter [18].
Atravs da classe EventEmitter possvel adicionar um
callback para tratar um determinado evento, atravs da
funo addListener ou on, bem como, lanar, emitir um
determinado evento, atravs da funo emit. Umexemplo de
uso desta classe pode ser visto na Figura 6.


Figura 6. Utilizao da classe EventEmitter

Este modelo de registro de callbacks associados a um
determinado evento, e um criador de eventos para serem
consumidos, pode ser definido como Publish-Subscribe [12].
Com isso, torna-se possvel haver mais de um callback
associado ao mesmo evento. Quando o evento ocorrer, o
node.js ir executar todos os callbacks associados ao evento
ocorrido. Isto pode ser visto na Figura 7.


Figura 7. Mais de um callback associado a um mesmo
evento.

No exemplo mostrado na Figura 7 h mais de um
callback associado a um mesmo evento, quando este evento
for emitido, todos os callbacks sero executados na ordem
emque foramassociados ao evento.
O EventEmitter utilizado pela maioria dos mdulos no
Node.js. Os que precisam fazer uso de emisso de eventos, se
utilizam desta classe. Isto pode ser feito de vrias formas,
dentre as quais podem ser citadas, o uso explcito do
EventEmitter no cdigo do mdulo, ou atravs de herena, na
qual a classe criada no mdulo estende EventEmitter, dessa
forma passa a possuir as funes definidas na mesma. Um
exemplo da segunda opo pode ser visto atravs da Figura 8.
Sendo esta a opo mais utilizada.


Figura 8. Classe herdando de EventEmitter

O Exemplo mostrado na Figura 8 foi retirado do cdigo
de umdos mdulos do Node.js, o mdulo stream. Nela h
uma funo construtora Stream, e uma chamada a funo
util.inherits, que indica que a classe Streamest herdando de
EventEmitter. Desta forma objetos criados utilizando a
funo construtora Stream, podemacessar funes definidas
por EventEmitter, como on, emit, dentre outras.

V. DIFICULDADES COM NODE.JS

Programao orientada a eventos se utiliza bastante de
callbacks, como javascript permite a passagemde funes
annimas, no seria incomum encontrar cdigos como o
mostrado na Figura 9.


Figura 9. Cdigo Sequencial com Node.js [19]

Devido a sua natureza assncrona, no h garantia na
ordemde execuo das chamadas efetuadas. O cdigo acima
tem a inteno de manter o controle na ordemde execuo
das chamadas. A medida em que se consegue manter o
controle sobre a ordem de execuo, acaba-se perdendo em
legibilidade e manutenibilidade do cdigo, gerando o
chamado Spaghetti Code.
Para solucionar essa problemtica h uma grande
quantidade de mdulos desenvolvidos pela comunidade.
Entre os quais podem ser citados, Step, Flow-js, dentre
outros. possvel verificar a utilizao da biblioteca Step na
Figura 10.


Figura 10. Step Exemplo de Uso

Verifica-se que atravs do uso do mdulo Step obtm-se
maior legibilidade no cdigo, alm de uma forma bem
simples de executar atividades de maneira seqencial. Um
ponto a notar que o framework no perde sua natureza
assncrona, o que o mdulo faz simplesmente passar a
prpria funo como callback, dessa forma o mdulo Step
controla a ordemde execuo.
Um outro ponto a ser trabalhado no desenvolvimento de
aplicaes comNode.js, a questo da utilizao dos vrios
processadores ou cores disponveis. O Node executa emum
nico processo, ou seja, single-threaded. Uma das solues
comuns utilizadas no mundo Node.js a execuo de
mltiplas instncias do processo [13]. H um mdulo
desenvolvido pela comunidade para este problema especfico,
o multi-node [20]. Este mdulo faz uso da capacidade dos
sistemas operacionais em compartilhar sockets entre
processos. Umexemplo de uso deste mdulo pode ser visto
na Figura 11.


Figura 11. Multi-node exemplo de utilizao.

Por se tratar de umframework relativamente novo, h
ainda diversos pontos a serem trabalhados para facilitar o
desenvolvimento de aplicaes utilizando o Node.js. A cada
dia a comunidade desenvolve novos mdulos visando atacar
os pontos a seremmelhorados no framework.


VI. CONSIDERAES FINAIS

Neste artigo possvel constatar como o paradigma de
programao orientada a eventos pode ser utilizada no lado
do servidor. Verifica-se tambm que o Node.js uma
ferramenta vivel para construo de aplicaes orientadas a
eventos. Foi possvel perceber tambmalgumas dificuldades
que podemser encontradas no desenvolvimento das mesmas.
O Node.js ainda um framework em processo de
maturao, sendo assim, o uso do mesmo deve passar por um
processo de estudo para verificar se o mesmo se aplica as
necessidades da aplicao emquesto.
Baseado nas referncias citadas, possvel constatar que
quando aplicado ao contexto correto e utilizando as melhores
prticas e padres para programao orientada a eventos, bem
como javascript, Node.js pode ser utilizado para produzir
sistemas orientados a eventos altamente escalveis e com alto
desempenho.


VII. REFERNCIAS

[1] M. Welsh, D. Culler, and E. Brewer, SEDA: An Architecture for Well-
Conditioned, Scalable Internet Services, ACM Symposium on
Operating Systems Principles, 2001.
[2] D. Kegel, The C10K Problem, http://www.kegel.com/c10k.html, 2011,
acessado emFevereiro de 2012.
[3] F. Dabek, N. Zeldovich, F. Kaashoek, D. Maziresmand R. Morris,
Event-Driven Programming for Robust Software, n the Proceedings of
SIGOPS European Workshop 2002, Saint-Emilion, France, 2002.
[4] F. Dabek, N. Zeldovich, F. Kaashoek, D. Maziresmand R. Morris,
Multiprocessor Support for Event-Driven Programs , In the Proceedings of
USENIX 2003, San Antonio, Texas, 2003.
[5] Nginx, Nginx, http://nginx.org/, 2012, acessado emFevereiro de2012.
[6] G-WAN, G-WAN Web Application Server, http://gwan.com/, 2012,
acessado emFevereiro de2012.
[7] Twisted, Twisted, http://twistedmatrix.com/trac/, 2012, acessado em
Fevereiro de2012.
[8] Event Machine, eventmachine @ Github, http://rubyeventmachine.com/,
2012, acessado emFevereiro de2012.
[9] Node.js, Node.js, http://nodejs.org/, 2012, acessado emFevereiro de
2012.
[10] O. Etzion, P. Niblett,, Event Processing in Action, Manning,, 2010.
[11] M. Cantelon, and TJ . Holowaychuk, Node.js in action, Manning, 2011.
[12] G. Hohpe, B. Woolf, Enterprise Integration Patterns: Desigining,
Building, and Deploying Messagin Systems,Addison-Wesley,2003.
[13] S. Tikov, S. Vinoski. Node.js: Using J avascript to Build Gugh
PerformanceNetwork Programs . Internet Computing, IEEE ,2010.
[14] Google. V8 javascript Engine. http://code.google.com/p/v8/, 2012,
acessado emFevereiro de2012.
[15] T. Hughes-Crouch. Up and Running With Node.js. OReilly, 2010.
[16] M. Lehmann. Libev. http://software.schmorp.de/pkg/libev.html, 2012,
acessado emFevereiro de2012.
[17] M. Lehmann. Libeio. http://software.schmorp.de/pkg/libeio.html, 2012,
acessado emFevereiro de2012.
[18] Node.js. EventEmitter. http://nodejs.org/docs/latest/api/events.html,
2012, acessado emFevereiro de2012.
[19] B. Michel. Evented Programming and its Patterns.
http://nono.github.com/Presentations/20110923_Evented_Programming/,
2012, acessado emFevereiro de2012.
[20] K. Zyp. Multi-Node. httphttps://github.com/kriszyp/multi-
node, 2012, acessado emFevereiro de2012.