miércoles, 29 de diciembre de 2010

Node.js: simplicidad y eficiencia

node.JS

Desde hace tiempo tenía pendiente escribir sobre Node.js (Node para los amigos). Hago una breve introducción primero para que se entienda por qué me parece importante:

Hace ya un par de años escribí un post hablando del resurgimiento de Javascript como lenguaje en todos lados, y la tendencia que veía entonces está empezando a ser notoria este año y creo que se va a afianzar el próximo.

El primero paso hacia un mayor uso de Javascript del lado del servidor fue la aparición de CommonJS como iniciativa para unificar detalles de las diferentes implementaciones, y es algo que está ganando bastante aceptación, especialmente en el soporte para los modules.

Node inició fuera de este estándar, pero luego se adaptó a CommonJS, y es un motor de Javascript del lado del servidor fuertemente basado en eventos y orientado principalmente a un manejo eficiente de comunicaciones en red. Se basa a su vez en el motor de Javascript V8, creado por Google y utilizado en Chrome, pero publicado como código abierto. Node también es código abierto con ncia MIT.

Lo notable de Node es que aprovecha la característica de Javascript como lenguaje y cultura, que a diferencia del resto del universo de la programación, siempre vio como algo natural el hacer llamadas no-bloqueantes.

Veamos la diferencia. Mientras en otros lenguajes cosas triviales como una consulta tienden a escribirse naturalmente como:

resultado = query( 'select * from Tabla');

en Javascript lo usual sería expresar esto como:

query( 'select * from Tabla', function (resultado) {
   // y aquí vemos qué hacemos con el resultado...
});

¿Cuál es la diferencia principal? Que la primer manera de llamada es bloqueante; es decir que mientras el resultado de la consulta no llega, el programa está detenido. En el segundo ejemplo, la llamada es no bloqueante, por lo que el resultado no se asigna a una variable sino que se pasa como parámetro a un callback (una función que será llamada al terminar la ejecución de la consulta, en este caso). En el ejemplo el callback se define en el mismo lugar para abreviar, pero podría ser una función definida en otra parte.

Lo importante de esta diferencia es que el estilo bloqueante de llamadas consume muchísimos recursos mientras se produce esa espera, que al involucrar acceso a disco o recursos de red puede ser por un tiempo importante, sobre todo al considerar una ambiente de alta concurrencia.

El modelo no-bloqueante o asincrónico, permite además manejar el procesamiento de esos callbacks dentro de un bucle de atención de eventos en lugar de necesitar threads separados para cada instancia. Y los threads son costosos y cuello de botella a la hora de escalar con mucha concurrencia.

Node aprovecha esta diferencia cultural de Javascript y brinda un entorno donde podemos realizar la mayor parte de las conexiones de red en forma no-bloqueante.

Veamos un ejemplo rápido que puede ilustrar la sencillez y eficiencia de Node en acción:

http = require('http');
Buffer = require('buffer').Buffer;
mega = 1024 * 1024;
bloque = new Buffer(mega);
for (var i=0; i<mega; i++) bloque[i] = 65; // Letra "A"
// SERVIDOR
http.createServer( function (pedido, respuesta) {
respuesta.writeHead(200);
respuesta.end(bloque);
}).listen(8000);

Las últimas cuatro líneas son la versión más básica de un web server en Node. ¿Sencillo, verdad?

Las primeras dos líneas utilizan el mecanismo de CommonJS de inclusión de módulos. El módulo HTTP permite acceso completo al protocolo como cliente o servidor y soporta cosas interesantísimas como la capacidad de devolver contenido como streaming. El módulo Buffer se utiliza para preparar bloques de datos binarios o crudos, no Unicode.

Las siguientes tres líneas solamente crean ese bloque de 1 Megabyte exacto de largo.

Lo más interesante son esas últimas cuatro (una sola sentencia, como se puede apreciar). Allí creamos una instancia del servidor web que atenderá en el puerto 8000 y al recibir cualquier pedido (HTTP request) responderá el bloque lleno con 1 Mb de letras A con status Ok (200) en la cabecera.

Pero lo más interesante es la manera en que se comporta el servidor si lo sometemos a una prueba de alta concurrencia. En pruebas con 100 requests concurrentes, Node llega a responder más de 800 requests por segundo (respondiendo 1 Mb para cada uno), lo que es un rendimiento asombroso. Estas características brillan en servicios de chat, presencia, colaboración o cualquier otro escenario donde típicamente deban soportarse muchas conexiones concurrentes.

Node tiene muchas otras ventajas, pero espero que hasta acá alcance para interesarlos. Lo ideal para conocer más sobre Node, además del sitio oficial, es la comunidad de artículos sobre usos y extensiones How to Node.

martes, 28 de diciembre de 2010

Kod: un editor de código (abierto) para OS X

Kod

Kod es un editor orientado a escribir código para OS X. Es de código abierto, bajo licencia MIT (modificada para no permitir vender el editor como tal) y alojado en GitHub.

Tiene algunas características muy interesantes, que me llamaron la atención y por lo que estoy empezando a usarlo con bastante buen resultado (listo lo que detallan en el sitio oficial, con mis comentarios):

  • Tiene un comportamiento muy asincrónico, y aprovecha el poder de los procesadores de múltiples núcleos que tenemos hoy día. Esto es algo que hace tiempo espero de más aplicaciones.¿Porqué tengo que esperar a que las cosas se terminen de grabar para poder seguir trabajando? Kod es muy eficiente al estar trabajando con múltiples archivos de diferentes tamaños.
  • El entorno de scripting está basado en el ascendente Node.js, sobre lo que tengo que escribir un próximo post en más detalle.
  • Interfaz de usuario inspirada en Chromium, utilizando tabs que pueden soltarse en ventanas independientes y volverse a unir, pero sobre todo, permitiendo escribir el nombre del archivo a editar directamente en la barra de direcciones, algo que es muy práctico al editar código, en lugar de tener que abrir un cuadro de diálogo.
  • Tiene algunas cosas que no usé, como que permite editar directamente archivos a través de HTTP (aunque no grabarlo, claro), y para cambiar estilos en el editor todo se hace mediante CSS 3.
  • Soporta al parecer 65 lenguajes o dialectos, y al menos tiene buen soporte para Ruby, JScript y Python por lo que vi hasta ahora.

Atención: para los que buscar una IDE, este es sólo un editor. Pero es muy interesante, parece ser activamente mantenido, y puede ser una competencia interesante a los tradicionales TextMate y Vim habituales en el mundo Mac.

Dejo como muestra una captura del editor en mi máquina:

Kod-screen

lunes, 27 de diciembre de 2010

La campaña Anti-IF

 

I have joined Anti-IF Campaign

Francesco Cirillo, de Italia, conocido por muchos como el creador de la Técnica Pomodoro para manejar el tiempo personal, inició tiempo atrás una campaña más específicamente orientada a los programadores:

El objetivo de esta campaña iniciada en 2007 es captar la atención en la comunidad de desarrollo sobre el abuso de técnicas procedurales en detrimento de las capacidades de orientación a objetos que los lenguajes que en general utilizamos tienen. El apuntar específicamente en contra del IF (y por extensión su derivado extremista, SWITCH/CASE) implica hacer foco en el valor del polimorfismo en lugar del abuso de condiciones que pueden expresarse en forma más clara y mantenible de otra manera.

El ejemplo canónico que presenta el sitio de la campaña es:


// Bond class
double calculateValue() {
   if(_type == BTP) { 
       return calculateBTPValue();
      } else if(_type == BOT) { 
       return calculateBOTValue();    
      } else {
       return calculateEUBValue();
      }
   }

 

¿Cuántas veces vemos código como éste? Peor aún, es probable que nosotros mismos seamos los culpables, tiempo atrás, o no tanto...

Entre otros problema, este código viola el principio Abierto/Cerrado (Open/Close) popularizado por el tío Bob Martin, ya que cada vez que un nuevo tipo de bono aparezca tendremos que "abrir" nuevamente esta clase para ampliar el tipo de cálculo. La solución es obvia, aunque no la vemos aplicada tan frecuentemente: utilizar polimorfismo basándonos herencia (aunque pronto puede que la herencia no se tan conveniente y cambiemos a composición). Veamos la respuesta propuesta en el sitio:


// Bond class
double calculateValue() {
_bondProfile.calculate();
}
// AbstractBondProfile class
abstract double calculate()

// BTPBondProfile class >> AbstractBondProfile
double calculate() {
...
}
// BOTBondProfile class >> AbstractBondProfile
double calculate() {
...
}
// EUBondProfile class >> AbstractBondProfile
double calculate() {
...
}

 

A partir de crear una clase base con un método abstracto, respetamos el principio Abierto/Cerrado porque podemos agregar más tipos de bono simplemente agregando nuevas subclases, sin tener que tocar (necesariamente) la base.

Es interesante ver la lista de gente que apoya la campaña, entre los que se encuentran nombres conocidos como David Laribee (conocido miembro de la comunidad Alt.NET), Kent Beck (el "padre" de Extreme Programming y JNunit), Dave Nicolette (otro reconocido agilista), y muchos otros.

 

 

 

 

viernes, 24 de diciembre de 2010

Regalo de navidad: Code & Beyond versión móvil

C&B telefoneado

Para quienes leen este blog usualmente desde su celular, acabamos de agregar un estilo mejorado para navegadores con pantallas reducidas, como teléfonos o iPods.

Esperamos que el formato les sea más cómodo para leer.

Si tienen instalada una aplicación de lectura de códigos de barras bi-dimensionales (la mayoría de los teléfonos la tienen actualmente) pueden apuntar su cámara directamente al código debajo para navegar hacia este blog:

Code & Beyond móvil

 

 

 

 

 

¡Felíces fiestas!

jueves, 23 de diciembre de 2010

Resultados de la Reunión Alt.Net en Buenos Aires

Alt.Net Hispano

Hace un par de fines de semana, el sábado 11 de diciembre, se realizó una nueva reunión del movimiento Alt.Net en Buenos Aires, en las remodeladas oficinas de Microsoft de Argentina, que duró todo el día.

Por las características de la reunión, más alguna dificultad con la conectividad, se hizo imposible capturar video, pero afortunadamente nos quedó este excelente resumen que publicó el amigo Pedro Wood, quien se vino para esta reunión desde Bariloche, nada menos. Pueden leer ahí un buen compendio de las sesiones en las que él participó y comentarios generales.

Dejo un par de fotos que tomé en los momentos de descanso del evento:

5285547260_787225a0fc.jpg

5285547018_9c3b7e4528.jpg

El set completo (son solo cuatro fotos) está disponible en Flickr.