SlideShare una empresa de Scribd logo
1 de 48
Going crazy with  Node.js  and  CakePHP ,[object Object],[object Object],Mariano Iglesias @mgiglesias
Hello world! ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Node.js... that's not CakePHP! ,[object Object],There are  different  solutions to different problems! ,[object Object],[object Object],[object Object],[object Object],[object Object]
What's the problem? ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Threads vs events ,[object Object]
What is Node.js? ,[object Object],V8 JavaScript engine Evented I/O + =
V8 Engine ,[object Object],[object Object],[object Object],Performance is king http://code.google.com/apis/v8/design.html
Evented I/O ,[object Object],[object Object],[object Object],db. query (). select ( '*' ). from ( 'users' ). execute ( function () { fs. readFile ( 'settings.json' ,   function () { // ... }); });
Libuv == Node.exe http_simple (/bytes/1024) over 1-gbit network, with 700 concurrent connections: windows-0.5.4  : 3869 r/s windows-latest  : 4990 r/s linux-latest-legacy  : 5215 r/s linux-latest-uv  : 4970 r/s
More stuff ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Should I throw away CakePHP? ,[object Object],There are  different  solutions to different problems!
First node.js server var   http   =   require ( 'http' ); http. createServer ( function (req,   res) { res. writeHead ( 200 , { 'Content-type' :   'text/plain' }); res. end ( 'Hello world!' ); }). listen ( 1337 ); console. log ( 'Server running at http://localhost:1337' );
Understanding the event loop ,[object Object],[object Object],var   http   =   require ( 'http' ); http. createServer ( function (req,   res) { console. log ( 'New request' ); // Block for five seconds var   now   =  new   Date (). getTime (); while ( new   Date (). getTime () <   now   +   5000 ) ; // Response res. writeHead ( 200 , {  'Content-type' :   'text/plain'  }); res. end ( 'Hello world!' ); }). listen ( 1337 ); console. log ( 'Server running at http://localhost:1337' );
What about multiple cores? ,[object Object],:1337 :1338 :1339 The  OS  approach var  http   =   require ( 'http' ), cluster = ...; var  server = http. createServer ( function (req,   res) { res. writeHead ( 200 , {  'Content-type' :  'text/plain'  }); res. end ( 'Hello world!' ); }); cluster (server). listen ( 1337 );
Packaged modules $ curl http://npmjs.org/install.sh | sh $ npm install db-mysql There are more than  3350  packages, and more than  14  are added each day
Packaged modules var   m   =   require ( './module' ); m. sum ( 1 ,   3 ,   function (err,   res) { if   (err) { return   console. log ( 'ERROR: '   +   err); } console. log ( 'RESULT IS: '   +   res); }); exports.sum   =   function (a,   b,   callback) { if   ( isNaN (a)   ||   isNaN (b)) { return   callback ( new   Error ( 'Invalid parameter' )); } callback ( null ,   a+b); };
Frameworks are everywhere ,[object Object],[object Object],[object Object],[object Object],[object Object],http://expressjs.com
Multiple environments var   express   =   require ( 'express' ); var   app   =   express. createServer (); app. get ( '/' ,   function (req,   res) { res. send ( 'Hello world!' ); }); app. listen ( 3000 ); console. log ( 'Server listening in http://localhost:3000' ); app. configure ( function () { app. use (express. bodyParser ()); }); app. configure ( 'dev' ,   function () { app. use (express. logger ()); }); $ NODE_ENV=dev node app.js
Middleware function   getUser (req,   res,   next) { if   (!req.params.id) { return   next (); }   else if   (!users[req.params.id]) { return   next ( new   Error ( 'Invalid user' )); } req.user   =   users[req.params.id]; next (); } app. get ( '/users/:id?' ,   getUser,   function (req,   res,   next) { if   (!req.user) { return   next (); } res. send (req.user); });
View rendering ,[object Object],app. configure ( function () { app. set ( 'views' ,   __dirname   +   '/views' ); app. set ( 'view engine' ,   'jade' ); }); app. get ( '/users/:id?' ,   function (req,   res,   next) { if   (!req.params.id) { return   next (); } if   (!users[req.params.id]) { return   next ( new   Error ( 'Invalid user' )); } res. send (users[req.params.id]); }); app. get ( '/users' ,   function (req,   res) { res. render ( 'index' , {   layout:   false , locals: {   users:   users   } }); }); html body h1 Node.js ROCKS ul - each user, id in users li a(href='/users/#{id}') #{user.name}
node-db ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],http://nodejsdb.org
node-db var  mysql   =   require ( 'db-mysql' ); new   mysql. Database ({ hostname:   'localhost' , user:   'root' , password:   'password' , database:   'db' }). connect ( function (err) { if   (err) { return   console. log ( 'CONNECT error: ' ,   err); } this . query (). select ([ 'id' ,   'email' ]). from ( 'users' ). where ( 'approved = ? AND role IN ?' , [ true , [   'user' ,   'admin'   ] ]). execute ( function (err,   rows,   cols) { if   (err) { return   console. log ( 'QUERY error: ' ,   err); } console. log (rows,   cols); }); });
Let's get to work
Sample application ,[object Object],[object Object]
Why are we doing this? ,[object Object],[object Object],[object Object],[object Object],$ siege -d1 -r10 -c25
Sample application CREATE TABLE `users`( `id` char(36) NOT NULL, `email` varchar(255) NOT NULL, `password` text NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ); CREATE TABLE `messages` (  `id` char(36) NOT NULL, `from_user_id` char(36) NOT NULL, `to_user_id` char(36) NOT NULL, `message` text NOT NULL, `created` datetime NOT NULL, PRIMARY KEY (`id`), KEY `from_user_id` (`from_user_id`), KEY `to_user_id` (`to_user_id`), CONSTRAINT `messages_from_user` FOREIGN KEY (`from_user_id`) REFERENCES `users` (`id`), CONSTRAINT `messages_to_user` FOREIGN KEY (`to_user_id`) REFERENCES `users` (`id`) );
Sample application ,[object Object],[ { &quot;Message&quot;: { &quot;id&quot;:&quot;4e4d8cf1-15e0-4b87-a3fc-62aa4c2971a2&quot;, &quot;message&quot;:&quot;Hello Mariano!&quot; }, &quot;FromUser&quot;: { &quot;id&quot;:&quot;4e4c2996-f964-4192-a084-19dc4c2971a2&quot;, &quot;name&quot;:&quot;Jane Doe&quot; }, &quot;ToUser&quot;: {&quot;name&quot;:&quot;Mariano Iglesias&quot;} }, { &quot;Message&quot;: { &quot;id&quot;:&quot;4e4d8cf5-9534-49b9-8cba-62bf4c2971a2&quot;, &quot;message&quot;:&quot;How are you?&quot; }, &quot;FromUser&quot;: { &quot;id&quot;:&quot;4e4c2996-f964-4192-a084-19dc4c2971a2&quot;, &quot;name&quot;:&quot;Jane Doe&quot; }, &quot;ToUser&quot;: {&quot;name&quot;:&quot;Mariano Iglesias&quot;} } ]
CakePHP code class   MessagesController   extends   AppController   { public function   incoming ( $userId ) { $since   = ! empty ( $this ->request->query[ 'since' ])   ?   urldecode ( $this ->request->query[ 'since' ]) :   null; if   ( empty ( $since )   ||   ! preg_match ( '/^{4}-{2}-{2} {2}:{2}:{2}$/' ,   $since ) ) { $since   =   '0000-00-00 00:00:00' ; } $messages   = ... $this ->autoRender   =   false; $this ->response-> type ( 'json' ); $this ->response-> body ( json_encode ( $messages )); $this ->response-> send (); $this -> _stop (); } }
CakePHP code $messages   =   $this ->Message-> find ( 'all' ,   array ( 'fields'   =>   array ( 'Message.id' , 'Message.message' , 'FromUser.id' , 'FromUser.name' , 'ToUser.name' ), 'joins'   =>   array ( array ( 'type'   =>   'INNER' , 'table'   =>   'users' , 'alias'   =>   'FromUser' , 'conditions'   =>   array ( 'FromUser.id = Message.from_user_id' ) ), array ( 'type'   =>   'INNER' , 'table'   =>   'users' , 'alias'   =>   'ToUser' , 'conditions'   =>   array ( 'ToUser.id = Message.to_user_id' ) ), ), 'conditions'   =>   array ( 'Message.to_user_id'   =>   $userId , 'Message.created >='   =>   $since ), 'order'   =>   array ( 'Message.created'   =>   'asc' ), 'recursive'   => - 1 ));
Node.js code: express var   express   =   require ( 'express' ), mysql   =   require ( 'db-mysql' ), port   =   1337 ; var   app   =   express. createServer (); app. get ( '/messages/incoming/:id' ,   function (req,   res){ var   r   = ... var   userId   =   req.params.id; if   (!userId) { return   r ( new   Error ( 'No user ID provided' )); } var   since   =   req.query.since ? req.query.since   :   false ; if   (!since ||   !/^{ 4 }-{ 2 }-{ 2 }   { 2 }:{ 2 }:{ 2 }$/. test (since)) { since   =   '0000-00-00 00:00:00' ; } new   mysql. Database (...). connect ( function (err) { if   (err) {   return   r (err); } ... }); }); app. listen (port); console. log ( 'Server running at http://localhost:'   +   port);
Node.js code: express ,[object Object],[object Object],var   r   =   function (err,   data) { if   (err) { console. log ( 'ERROR: '   +   err); res. writeHead ( 503 ); return   res. end (); } res.charset   =   'UTF-8' ; res. contentType ( 'application/json' ); res. header ( 'Access-Control-Allow-Origin' ,   '*' ); res. send (data); };
Node.js code: node-db db. query (). select ({ 'Message_id' :   'Message.id' ,   'Message_message' :   'Message.message' ,   'FromUser_id' :   'FromUser.id' , 'FromUser_name' :   'FromUser.name' ,   'ToUser_name' :   'ToUser.name' }). from ({ 'Message' :   'messages' }). join ({ type:   'INNER' , table:   'users' , alias:   'FromUser' , conditions:   'FromUser.id = Message.from_user_id' }). join ({ type:   'INNER' , table:   'users' , alias:   'ToUser' , conditions:   'ToUser.id = Message.to_user_id' }). where ( 'Message.to_user_id = ?' , [   userId   ]). and ( 'Message.created >= ?' , [   since   ]). order ({ 'Message.created' :   'asc' }). execute ( function (err,   rows) { ... });
Node.js code: node-db function (err,   rows) { db. disconnect (); if   (err) { return   r (err); } for   ( var   i= 0 ,   limiti=rows.length;   i   <   limiti;   i++) { var   row   = {}; for   ( var   key   in   rows [i] ) { var   p   =   key. indexOf ( '_' ), model   =   key. substring ( 0 ,   p), field   =   key. substring (p+ 1 ); if   (!row [model] ) { row [model]   = {}; } row [model][field]   =   rows [i][key] ; } rows [i]   =   row; } r ( null ,   rows); }
Long polling ,[object Object],[object Object],function   fetch () { $. ajax ({ url: ..., async:   true , cache:   false , timeout:   60   *   1000 , success:   function (data) { ... setTimeout ( fetch (),   1000 ); }, error: ... }); }
Bonus tracks
#1 Pooling connections
Pooling connections ,[object Object],var   mysql   =   require ( 'db-mysql' ), generic_pool   =   require ( 'generic-pool' ); var   pool   =   generic_pool. Pool ({ name:   'mysql' , max:   30 , create:   function (callback) { new   mysql. Database ({ ... }). connect ( function (err) { callback (err,   this ); }); }, destroy:   function (db) { db. disconnect (); } }); pool. acquire ( function (err,   db) { if   (err) { return   r (err); } ... pool. release (db); });
#2 Clustering express
Clustering express ,[object Object],var   cluster   =   require ( 'cluster' ), port   =   1337 ; cluster ( 'app' ). on ( 'start' ,   function () { console. log ( 'Server running at http://localhost:'   +   port); }). on ( 'worker' ,   function (worker) { console. log ( 'Worker #'   +   worker.id   +   ' started' ); }). listen (port); var   express   =   require ( 'express' ), generic_pool   =   require ( 'generic-pool' ); var   pool   =   generic_pool. Pool ({ ... }); module.exports   =   express. createServer (); module.exports. get ( '/messages/incoming/:id' ,   function (req,   res) { pool. acquire ( function (err,   db) { ... }); });
Clustering express
#3 Dealing with parallel tasks
Dealing with parallel tasks ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],https://github.com/caolan/async
Dealing with parallel tasks var   async   =   require ( 'async' ); async. waterfall ([ function (callback) { callback ( null ,   4 ); }, function (id,   callback) { callback ( null , { id:   id, name:   'Jane Doe' }); }, function (user,   callback) { console. log ( 'USER: ' ,   user); callback ( null ); } ]); $ node app.js USER:  { id: 4, name: 'Jane Doe' }
#4 Unit testing
Unit testing ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],https://github.com/caolan/nodeunit
Unit testing var  nodeunit =  require (' nodeunit' ); exports[ 'group1' ] =   nodeunit. testCase ({ setUp:   function (cb) { cb (); }, tearDown:   function (cb) { cb (); }, test1:   function (test) { test. equals ( 1 + 1 ,   2 ); test. done (); }, test2:   function (test) { test. expect ( 1 ); ( function () { test. equals ( 'a' ,   'a' ); })(); test. done (); } }); $ nodeunit tests.js nodeunit.js ✔  group1 – test1 ✔  group1 – test2
Questions?
Thanks! ,[object Object],@mgiglesias http://marianoiglesias.com.ar

Más contenido relacionado

La actualidad más candente

Controlling The Cloud With Python
Controlling The Cloud With PythonControlling The Cloud With Python
Controlling The Cloud With Python
Luca Mearelli
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with Moose
Dave Cross
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
diego_k
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
PrinceGuru MS
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
clkao
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
Masahiro Nagano
 

La actualidad más candente (20)

Moose - YAPC::NA 2012
Moose - YAPC::NA 2012Moose - YAPC::NA 2012
Moose - YAPC::NA 2012
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)
 
Controlling The Cloud With Python
Controlling The Cloud With PythonControlling The Cloud With Python
Controlling The Cloud With Python
 
To Batch Or Not To Batch
To Batch Or Not To BatchTo Batch Or Not To Batch
To Batch Or Not To Batch
 
About Data::ObjectDriver
About Data::ObjectDriverAbout Data::ObjectDriver
About Data::ObjectDriver
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with Moose
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojo
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
Beyond Phoenix
Beyond PhoenixBeyond Phoenix
Beyond Phoenix
 
Esprima - What is that
Esprima - What is thatEsprima - What is that
Esprima - What is that
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기RESTful API 제대로 만들기
RESTful API 제대로 만들기
 

Destacado

Integrating Node.js with PHP
Integrating Node.js with PHPIntegrating Node.js with PHP
Integrating Node.js with PHP
Lee Boynton
 

Destacado (6)

Behind the scenes of Real-Time Notifications
Behind the scenes of Real-Time NotificationsBehind the scenes of Real-Time Notifications
Behind the scenes of Real-Time Notifications
 
Concurrency, Robustness & Elixir SoCraTes 2015
Concurrency, Robustness & Elixir SoCraTes 2015Concurrency, Robustness & Elixir SoCraTes 2015
Concurrency, Robustness & Elixir SoCraTes 2015
 
Elixir Phoenix
Elixir PhoenixElixir Phoenix
Elixir Phoenix
 
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - WisemblySymfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
 
Integrating Node.js with PHP
Integrating Node.js with PHPIntegrating Node.js with PHP
Integrating Node.js with PHP
 
Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907
 

Similar a Going crazy with Node.JS and CakePHP

Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 
Node js presentation
Node js presentationNode js presentation
Node js presentation
martincabrera
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
Tom Croucher
 
Владимир Мигуро "Дао Node.js"
Владимир Мигуро "Дао Node.js"Владимир Мигуро "Дао Node.js"
Владимир Мигуро "Дао Node.js"
EPAM Systems
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by express
Shawn Meng
 
P H P Part I I, By Kian
P H P  Part  I I,  By  KianP H P  Part  I I,  By  Kian
P H P Part I I, By Kian
phelios
 
JavaScript Sprachraum
JavaScript SprachraumJavaScript Sprachraum
JavaScript Sprachraum
patricklee
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
Alex Su
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
elliando dias
 

Similar a Going crazy with Node.JS and CakePHP (20)

Building your first Node app with Connect & Express
Building your first Node app with Connect & ExpressBuilding your first Node app with Connect & Express
Building your first Node app with Connect & Express
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Web program-peformance-optimization
Web program-peformance-optimizationWeb program-peformance-optimization
Web program-peformance-optimization
 
Node js presentation
Node js presentationNode js presentation
Node js presentation
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Владимир Мигуро "Дао Node.js"
Владимир Мигуро "Дао Node.js"Владимир Мигуро "Дао Node.js"
Владимир Мигуро "Дао Node.js"
 
RingoJS
RingoJSRingoJS
RingoJS
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHP
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by express
 
P H P Part I I, By Kian
P H P  Part  I I,  By  KianP H P  Part  I I,  By  Kian
P H P Part I I, By Kian
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express
 
JavaScript Sprachraum
JavaScript SprachraumJavaScript Sprachraum
JavaScript Sprachraum
 
루비가 얼랭에 빠진 날
루비가 얼랭에 빠진 날루비가 얼랭에 빠진 날
루비가 얼랭에 빠진 날
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
 
working with PHP & DB's
working with PHP & DB'sworking with PHP & DB's
working with PHP & DB's
 
NodeJS
NodeJSNodeJS
NodeJS
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 

Más de Mariano Iglesias (8)

Go nuts with Go and PHP
Go nuts with Go and PHPGo nuts with Go and PHP
Go nuts with Go and PHP
 
ElasticSearch: la tenés atroden Google
ElasticSearch: la tenés atroden GoogleElasticSearch: la tenés atroden Google
ElasticSearch: la tenés atroden Google
 
Workana: work in your underwear and still get paid
Workana: work in your underwear and still get paidWorkana: work in your underwear and still get paid
Workana: work in your underwear and still get paid
 
Random tips that will save your project's life
Random tips that will save your project's lifeRandom tips that will save your project's life
Random tips that will save your project's life
 
node-db: La excusa perfecta para hablar de C++ y Node.js
node-db: La excusa perfecta para hablar de C++ y Node.jsnode-db: La excusa perfecta para hablar de C++ y Node.js
node-db: La excusa perfecta para hablar de C++ y Node.js
 
ONGs como Extreme Startups
ONGs como Extreme StartupsONGs como Extreme Startups
ONGs como Extreme Startups
 
Node.js - Eventos para Todos
Node.js - Eventos para TodosNode.js - Eventos para Todos
Node.js - Eventos para Todos
 
Things that suck... and some that don't
Things that suck... and some that don'tThings that suck... and some that don't
Things that suck... and some that don't
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Último (20)

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 

Going crazy with Node.JS and CakePHP

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9. Libuv == Node.exe http_simple (/bytes/1024) over 1-gbit network, with 700 concurrent connections: windows-0.5.4 : 3869 r/s windows-latest : 4990 r/s linux-latest-legacy : 5215 r/s linux-latest-uv : 4970 r/s
  • 10.
  • 11.
  • 12. First node.js server var http = require ( 'http' ); http. createServer ( function (req, res) { res. writeHead ( 200 , { 'Content-type' : 'text/plain' }); res. end ( 'Hello world!' ); }). listen ( 1337 ); console. log ( 'Server running at http://localhost:1337' );
  • 13.
  • 14.
  • 15. Packaged modules $ curl http://npmjs.org/install.sh | sh $ npm install db-mysql There are more than 3350 packages, and more than 14 are added each day
  • 16. Packaged modules var m = require ( './module' ); m. sum ( 1 , 3 , function (err, res) { if (err) { return console. log ( 'ERROR: ' + err); } console. log ( 'RESULT IS: ' + res); }); exports.sum = function (a, b, callback) { if ( isNaN (a) || isNaN (b)) { return callback ( new Error ( 'Invalid parameter' )); } callback ( null , a+b); };
  • 17.
  • 18. Multiple environments var express = require ( 'express' ); var app = express. createServer (); app. get ( '/' , function (req, res) { res. send ( 'Hello world!' ); }); app. listen ( 3000 ); console. log ( 'Server listening in http://localhost:3000' ); app. configure ( function () { app. use (express. bodyParser ()); }); app. configure ( 'dev' , function () { app. use (express. logger ()); }); $ NODE_ENV=dev node app.js
  • 19. Middleware function getUser (req, res, next) { if (!req.params.id) { return next (); } else if (!users[req.params.id]) { return next ( new Error ( 'Invalid user' )); } req.user = users[req.params.id]; next (); } app. get ( '/users/:id?' , getUser, function (req, res, next) { if (!req.user) { return next (); } res. send (req.user); });
  • 20.
  • 21.
  • 22. node-db var mysql = require ( 'db-mysql' ); new mysql. Database ({ hostname: 'localhost' , user: 'root' , password: 'password' , database: 'db' }). connect ( function (err) { if (err) { return console. log ( 'CONNECT error: ' , err); } this . query (). select ([ 'id' , 'email' ]). from ( 'users' ). where ( 'approved = ? AND role IN ?' , [ true , [ 'user' , 'admin' ] ]). execute ( function (err, rows, cols) { if (err) { return console. log ( 'QUERY error: ' , err); } console. log (rows, cols); }); });
  • 23. Let's get to work
  • 24.
  • 25.
  • 26. Sample application CREATE TABLE `users`( `id` char(36) NOT NULL, `email` varchar(255) NOT NULL, `password` text NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ); CREATE TABLE `messages` ( `id` char(36) NOT NULL, `from_user_id` char(36) NOT NULL, `to_user_id` char(36) NOT NULL, `message` text NOT NULL, `created` datetime NOT NULL, PRIMARY KEY (`id`), KEY `from_user_id` (`from_user_id`), KEY `to_user_id` (`to_user_id`), CONSTRAINT `messages_from_user` FOREIGN KEY (`from_user_id`) REFERENCES `users` (`id`), CONSTRAINT `messages_to_user` FOREIGN KEY (`to_user_id`) REFERENCES `users` (`id`) );
  • 27.
  • 28. CakePHP code class MessagesController extends AppController { public function incoming ( $userId ) { $since = ! empty ( $this ->request->query[ 'since' ]) ? urldecode ( $this ->request->query[ 'since' ]) : null; if ( empty ( $since ) || ! preg_match ( '/^{4}-{2}-{2} {2}:{2}:{2}$/' , $since ) ) { $since = '0000-00-00 00:00:00' ; } $messages = ... $this ->autoRender = false; $this ->response-> type ( 'json' ); $this ->response-> body ( json_encode ( $messages )); $this ->response-> send (); $this -> _stop (); } }
  • 29. CakePHP code $messages = $this ->Message-> find ( 'all' , array ( 'fields' => array ( 'Message.id' , 'Message.message' , 'FromUser.id' , 'FromUser.name' , 'ToUser.name' ), 'joins' => array ( array ( 'type' => 'INNER' , 'table' => 'users' , 'alias' => 'FromUser' , 'conditions' => array ( 'FromUser.id = Message.from_user_id' ) ), array ( 'type' => 'INNER' , 'table' => 'users' , 'alias' => 'ToUser' , 'conditions' => array ( 'ToUser.id = Message.to_user_id' ) ), ), 'conditions' => array ( 'Message.to_user_id' => $userId , 'Message.created >=' => $since ), 'order' => array ( 'Message.created' => 'asc' ), 'recursive' => - 1 ));
  • 30. Node.js code: express var express = require ( 'express' ), mysql = require ( 'db-mysql' ), port = 1337 ; var app = express. createServer (); app. get ( '/messages/incoming/:id' , function (req, res){ var r = ... var userId = req.params.id; if (!userId) { return r ( new Error ( 'No user ID provided' )); } var since = req.query.since ? req.query.since : false ; if (!since || !/^{ 4 }-{ 2 }-{ 2 } { 2 }:{ 2 }:{ 2 }$/. test (since)) { since = '0000-00-00 00:00:00' ; } new mysql. Database (...). connect ( function (err) { if (err) { return r (err); } ... }); }); app. listen (port); console. log ( 'Server running at http://localhost:' + port);
  • 31.
  • 32. Node.js code: node-db db. query (). select ({ 'Message_id' : 'Message.id' , 'Message_message' : 'Message.message' , 'FromUser_id' : 'FromUser.id' , 'FromUser_name' : 'FromUser.name' , 'ToUser_name' : 'ToUser.name' }). from ({ 'Message' : 'messages' }). join ({ type: 'INNER' , table: 'users' , alias: 'FromUser' , conditions: 'FromUser.id = Message.from_user_id' }). join ({ type: 'INNER' , table: 'users' , alias: 'ToUser' , conditions: 'ToUser.id = Message.to_user_id' }). where ( 'Message.to_user_id = ?' , [ userId ]). and ( 'Message.created >= ?' , [ since ]). order ({ 'Message.created' : 'asc' }). execute ( function (err, rows) { ... });
  • 33. Node.js code: node-db function (err, rows) { db. disconnect (); if (err) { return r (err); } for ( var i= 0 , limiti=rows.length; i < limiti; i++) { var row = {}; for ( var key in rows [i] ) { var p = key. indexOf ( '_' ), model = key. substring ( 0 , p), field = key. substring (p+ 1 ); if (!row [model] ) { row [model] = {}; } row [model][field] = rows [i][key] ; } rows [i] = row; } r ( null , rows); }
  • 34.
  • 37.
  • 39.
  • 41. #3 Dealing with parallel tasks
  • 42.
  • 43. Dealing with parallel tasks var async = require ( 'async' ); async. waterfall ([ function (callback) { callback ( null , 4 ); }, function (id, callback) { callback ( null , { id: id, name: 'Jane Doe' }); }, function (user, callback) { console. log ( 'USER: ' , user); callback ( null ); } ]); $ node app.js USER: { id: 4, name: 'Jane Doe' }
  • 45.
  • 46. Unit testing var nodeunit = require (' nodeunit' ); exports[ 'group1' ] = nodeunit. testCase ({ setUp: function (cb) { cb (); }, tearDown: function (cb) { cb (); }, test1: function (test) { test. equals ( 1 + 1 , 2 ); test. done (); }, test2: function (test) { test. expect ( 1 ); ( function () { test. equals ( 'a' , 'a' ); })(); test. done (); } }); $ nodeunit tests.js nodeunit.js ✔ group1 – test1 ✔ group1 – test2
  • 48.

Notas del editor

  1. ** NORMALLY DOING: It&apos;s waiting. You get a request, query the DB, and wait for results. You write to a file, and wait for it to be written. You encode a video, and wait for it to complete. ** CACHING: File caching, Memcached ** WORKERS: Use robot plugin, or Gearman, or ActiveMQ / RabbitMQ ** FASTER DB: NoSQL (MongoDB, CouchDB)
  2. You can&apos;t simply spawn a new process or thread for each connection NGINX is event based, so memory usage is low APACHE spawns a thread per request (or process depending on configuration) THREADS spend a lot of time being blocked waiting for I/O operations EVENTS are better when more time is spent waiting on external resources
  3. ** V8: Without DOM parts
  4. ** PROPERTIES: Object properties can be changed at runtime in JS: property dictionaries Instance variables have fixed offsetts set by compiler. V8 creates hidden classes, one for each property added and class transitions show changes to object properties (only first time) ** MACHINE CODE: when first executed JS is compiled into machine code, no intermediate byte code ** GARBAGE: when running GC, program stops. Each GC cycle only process part of the heap.
  5. ** LIBEIO: by Marc Lehmann. Can be used with any event library, or in POLLING mode. Relies only on POSIX threads. Uses threads internally, and used by Node.JS for file/network access, integrated in node to LIBEV ** LIBEV: also by Marc Lehmann. asynchronous notification of file descriptor changes through ev_io() ** ReadFile(): lots of JS code, on top of fs.open(), which is a wrapper around C++ Open(), which uses libeio
  6. Node on Windows is not loosing significant performance compared to Linux
  7. ** BUFFER: Outside of V8 heap. Conversion to JS through encoding (binary, utf8, ascii, etc.) ** C-ARES: gethostbyname(), custom DNS queries ** CHILD_PROCESSES: fork() is in JS land, special case of spawn(), with IPC messaging capabilities ** CRYPTO: create hashes, ciphers with different algorithms, signs with private keys, and verify signatures ** HTTP_PARSER: NO allocation, NO buffer ** TIMER: setTimeout() is one time, setInterval() is repeated
  8. ** SINGLE THREAD: Since node runs in a single thread, anything blocking that thread blocks node from processing other requests ** YOUR code: if your code uses I/O, that I/O is NON blocking ** I/O calls are the point at which Node.js switches between different requests. So Node.js expects requests to be done very fast. Intensive CPU should be done in another process
  9. Since Node.JS runs in a single process, its bound to a single CPU ** OS approach: the kernel load balances connections across processes ** CLUSTER: uses several workers (in different CPUs), we will cover this later
  10. ** PACKAGES can be installed locally or globally
  11. ** COMMONJS: defines JS APIs for any purpose, such as server side JS. Amongst the things it defines, are modules ** The EXPORTS object is created by the module system. If you want your module to be a class, assign the export object to MODULE.EXPORTS
  12. ** ENVIRONMENTS: Can specify different middleware for each environment, and change settings ** MIDDLEWARE: for manipulating all requests, or for specific routes ** ROUTING: Including support for HTTP methods ** VIEW RENDERING: with different template engines, and including partials (sort of like CakePHP elements) ** SESSION SUPPORT: part of Connect, can be configured even with Redis
  13. ** MIDDLEWARES: order is important. ** BodyParser() allows the parsing of forms (including JSON posted data as part of body) ** Other middlewares include: cookieParser(), session()
  14. With route middleware, it&apos;s easy to add authentication
  15. ** JADE is one of the view engines available: $ npm install jade
  16. ** CakePHP APP: including the use Auth with Form authentication ** JSON endpoint first in CakePHP, then in Node.js An alternative to the JSON endpoint is to use WEB SOCKETS, which offers a bi-directional communication channel over TCP. Its API is still being standarized by the W3C. The Node.JS module SOCKET.IO has great support for web sockets, and its client code works on almost every browser
  17. ** SIEGE: 25 concurrent users, 10 repetitions, 1 random secs delay ** NODE.JS: Using EXPRESS
  18. ** Even if you don&apos;t add CONSTRAINTS, always REMEMBER to add a KEY for each field that is to be used as foreign keys
  19. ** writeHead(statusCode, headersObject) ** ACCESS CONTROL: a wildcard, or an URI ** res.send(): automatically converts object to JSON string
  20. ** We are now doing a whole bunch of HTTP requests, which is not optimal, we need to reduce them to the bare minimum ** LONG polling: when a response is obtained, we schedule a new request ** CODE: when error, ALSO schedule a new request
  21. ** Allows prioritization in the queue ** Can handle idle timeouts (time a resource can go unused before it is destroyed)
  22. ** CLUSTER: can be extended via plugins. Spawns one worker per CPU. Handles signals and different types of shutdown. Can resucitate workers.
  23. ** COLLECTIONS: forEach, map, filter, and others ** SERIES(): runs in order, stops if one fails (error first arg). Calls final callback once they are all done (or ERRORED), with an array of all arguments sent to each task ** PARALLEL(): similar to SERIES(), does not stop on error ** WATERFALL(): like SERIES(), but each task pass its result as an argument to the next task
  24. ** EXPORT: create a module and define the test groups as elements of the module ** EXPECT(): specify how many assertions are expected to run in a test ** DONE(): ALL TESTS should call this. Marks the test as done