NodeJS: Shared State Concurrency y WebMatrix

Este post tiene como objetivo tratar dos temas en paralelo.
En primera medida, quiero mostrar cómo con WebMatrix 3.0, podemos crear sitios wen 3 plataformas distintas:
1. PHP
2. ASP.NET (Razor)
3. NodeJS

De esta manera, estaremos creando la misma aplicación web usando las tres plataformas y todo esto solo en 15 minutos.

El segundo tema que quiero tratar en paralelo es una particularidad en NodeJS que es muy importante tener en cuenta a la hora de manejar el estado de una aplicación Web, pues el comportamiento es bien distinto a lo esperado en ambientes como PHP o .NET.

Gran parte de la discusión acerca de Node.js está centrada en sus capacidades para atender mucha, pero mucha concurrencia.

En términos simples, Node es un framework que ofrece a los desarrolladores una manera poderosa para diseñar aplicaciones de networking que se van a ejecutar realmente bien en comparación con otras soluciones del mainstream, SIEMPRE Y CUANDO, los desarrolladores comprendan los tradeoffs o las trampillas que pueden existir detrás de lo que hace que Node se comporte tan bien.

Y cuando hablamos de esto, básicamente estamos hablando de Shared State Concurrency o Concurrencia de Estado Compartido. A qué me refiero con esto?

Básicamente a que en NodeJS no hay una separación de sesiones en cada llamado al server, porque en Node, todo corre en un solo hilo, a diferencia de PHP o .NET. Por esto, es muy importante ser supremamente cuidadosos con la forma en que Javascript accede a las variables de la aplicación, pues cualquier modificación afectará al resto de los llamados.

Esto, obviamente no quiere decir que manejos de información por sesión no se puedan lograr. Solo que se ejecutan de una manera distinta a como estamos acostumbrados.

Para ejemplificar esta situación, he creado estas tres páginas web dinámicas que hacen lomismo: Inicializan un arreglo de strings, lo muestran en la página y luego lo eliminan. En ASP.NET y PHP, se espera que cada vez que un usuario ingrese, el arreglo se reinicie, mostrando siempre elementos. Pero en NodeJs esto no ocurre dado que Node corre sobre un solo hilo. Entonces cuando el arreglo se elimina y un nuevo usuario hace una petición al sitio, éste va a encontrar el arreglo vacío, pues el estado se comparte con todos los requests.

Veamos el código para cada caso y luego un video con la demostración:

PHP

 <?php 
   $metallicaAlbums=array( '...And justice for all', 'Ride the Lightning' ); 
?> 

<html>
 <body> 
   <?php 
       echo '<b>'.join($metallicaAlbums,'<br>').'</b>'; 
       $metallicaAlbums=array(); 
       echo '<br>'; echo '<b>'.join($metallicaAlbums,'<br>').'</b>'; 
   ?>
   <br> All Done. 
  </body> 
</html

.NET (Razor)

 @{ 
    var metallicaAlbums=new string[]{"...And Justice For All", "Ride the Lightning"}; 
} 

<!DOCTYPE html> 
   <html lang="en"> 
     <head> 
        <meta charset="utf-8" /> 
        <title></title> 
     </head> 
     <body> 
         My fav Metallica's Albums are:<br> 
         <b>@Html.Raw(string.Join("<br>",metallicaAlbums))</b> 
         @{metallicaAlbums=new string[2];} 
         <br>
         My fav Metallica's Albums are:<br> 
         <b>@Html.Raw(string.Join("<br>",metallicaAlbums))</b>
     </body>
</html> 

Node JS

nodematrix

 var http = require('http');
var metallicaAlbums=[ '...And justice for all', 'Ride the Lightning' ]; 

http.createServer(function (req, res) 
{ 
    var html = '<b>' + metallicaAlbums.join('<br>') + '</b>'; 
    if (metallicaAlbums.length < 1) html +=  
        'Oooops, they are gone!!! :( </b>'; 
    metallicaAlbums = []; 
    
    res.writeHead(200, { 'Content-Type': 'text/html' }); 
    res.end("These are my favourite Metallica Albums:<br>" + html); })
      .listen(process.env.PORT || 8080); 

Demo en Video