Tag Archives: erlang

Joe Armstrong y Erlang

Llevo bastante tiempo hablando de Erlang, y nunca había comentado la mejor fuente que había encontrado para descubrir el lenguaje y adentrarse en la programación concurrente de la mano de uno de sus creadores: Joe Armstrong. La fuente, referida como tal, es el libro que escribió Joe Armstrong por la editorial Pragmatic Programmers:

Programming Erlang
Joe Armstrong; Pragmatic Bookshelf 2007

El libro tiene una sección inicial que nos adentra en el problema que se encontró el autor, el porqué es necesario un lenguaje como Erlang y, sobre todo, un acercamiento al mismo desde la perspectiva de alguien que sabe poco o nada de programación. Es una lectura rápida y amena, facilitada por la claridad del código acompañada.

La única pega, quizás, es que el libro se queda corto a nivel de profundidad, es decir, el tema de OTP lo trata de pasada solo viendo un poco los gen_servers, así como la forma de empaquetado y puesta en producción. El entorno, la concurrencia, la distribución, todo queda en un estadio incial que puede abrumar e incluso dar la sensación de ser muy amplio al principio, pero cuando entramos en harina, se ve que nos falta más información. No obstante, tenemos una buena base y se completa todo con la información que el propio Armstrong ha dejado en la web del lenguaje.

Una lectura muy aconsejable para quien se quiera adentrar en la programación en Erlang y su entorno.

Comet ha muerto, ¡larga vida a websockets!

Leyendo el artículo de Joe Armstrong, sobre este mismo título, comenta que con la aparición de websockets (una nueva característica que ha aparecido en HTML5), el sistema comet y otros derivados, están abocados a la extinción.

Desde siempre, el sistema HTTP, llamado también web, ha sido un sistema cliente-servidor, donde el cliente siempre ha sido el navegador web, o cualquier herramienta que pudiese hacer una petición HTTP hacia un servidor, y el servidor, un ente pasivo, se encargaba de procesar la petición y retornar una respuesta. Nada más.

Una de las implementaciones más usadas por este sistema se produce gracias a la característica de HTTP 1.1 de mantener viva la conexión (keep alive) permitiendo al navegador realizar más peticiones y al servidor encauzar una respuesta progresiva, como una lluvia de estrellas (cometas) es el streaming, ya que el sistema puede enviar datos de vídeo progresivamente.

El problema viene dado, también, por la propia especificación de HTTP 1.1, donde se indica que sólo puede haber dos conexiones simultáneas con entre navegador y servidor, con lo que, el uso en una página web con hoja de estilos y bastantes imágenes puede no ser muy aconsejable.

¿Qué aporta de nuevo o de mejorado websockets? a través de HTML y JavaScript de forma simple, se establece una conexión con el servidor dada una URL y un sub-protocolo en el que deben de hablar. Una vez conectado, los elementos html pueden tener eventos del tipo: onopen, onmessage, onclose; indicando los tres eventos que pueden darse en la conexión y el diálogo abierto con el servidor.

Hay que recordar que la interacción vendrá dada por el servidor, esto es que, un programa ejecutándose en el servidor (que no tiene porqué ser de tipo web) puede enviar un evento al puerto especificado por el cliente y el mensaje ser recogido por el navegador y dárselo al elemento al que haga referencia el propio mensaje.

De momento, en Google Chrome se encuentra operativo y se puede probar. En el artículo de Joe Armstrong se puede descargar un código en Erlang para el servidor y un código HTML para el navegador.

Realizaré pruebas y ya comentaré la impresión que me cause el sistema.

La Historia de Erlang

He encontrado un documento (en inglés) que redacta la historia de Erlang contada por su desarrollador principal, en los laboratorios de Ericsson:

Erlang fue diseñado para escribir programas concurrentes que se ejecutasen eternamente. Erlang usa procesos concurrentes para estructurar el programa. Estos procesos no tienen memoria compartida y se comunican por paso de mensajes asíncronos. Los procesos de erlang son ligeros y pertenecen al lenguaje, no al sistema operativo. Erlang tiene mecanismos que permiten que los programas cambien on-the-fly (en vivo) así, esos programas pueden evolucionar y cambiar sin detener su ejecución. Estos mecanismos simplifican la construcción de software implementando sistemas non-stop (que no se detienen).

El desarrollo inicial de Erlang tuvo lugar en 1986 en el Laboratorio de Computación de Ericsson. Erlang fue diseñado con un objetivo específico en mente: proporcionar una mejor forma de programar aplicaciones de telefonía. En ese momento, las aplicaciones de telefonía eran atípicas del tipo de problemas que podían resolver los lenguajes de programación convencionales. Las aplicaciones de telefonía son, por su naturaleza, altamente concurrentes: un simple switch debe manejar decenas o cientos de miles de transacciones simultáneas. Tales transacciones son intrínsecamente distribuidas y el software se espera que sea altamente tolerante a fallos. Cuando el software que controla los teléfonos falla, sale en los periódicos, algo que no ocurre cuando fallan las aplicaciones de escritorio. El software de telefonía debe también cambiar on-the-fly, esto es, sin perder el servicio mientras se realiza una actualización del código. El software de telefonía debe también operar en tiempo real, con ajustados requisitos de tiempo para algunas operaciones, y más relajado tiempo en otras clases de operaciones.

Como puede leerse en el extracto, Joe Armstrong, fijó los requisitos de Erlang en solucionar los problemas de un entorno altamente concurrente, que no puede permitirse caer y que debe de actualizarse sin pérdida de servicio.

Actualmente, esta definición casa con casi la mayor parte de servicios en Internet.

Reia: Ruby sobre Erlang

Al igual que en Java se pueden ejecutar lenguajes scripting tales como Ruby (JRuby), Python (Jython), Groovy… es posible hacer esto mismo en otros lenguajes, como C y Erlang.

Erlang, es un lenguaje funcional, del que ya hablé en otro artículo, lo cual tiene sus ventajas para ciertos algoritmos… pero también sus inconvenientes para otro tipo de algoritmos, por lo que el poder combinarlo con lenguajes de scripting tan potentes como Ruby, es una forma de poder acelerar nuestros desarrollos… allanamos el camino quitando todas las piedras :-)

El sistema que hace esto es Reia. Este sistema, escrito en erlang y reia (casi la misma sintaxis que Ruby), da las capacidades de un lenguaje dinámico sobre un lenguaje funcional, dando la posibilidad de escribir código tanto en erlang como en reia e ir alternando. El resultado siguen siendo los archivos beam que la máquina de Erlang interpreta y ejecuta sin problemas.

CouchDB: REST y Base de datos documental

Tal y como comentaba en otro artículo anterior, el sistema REST permite un acceso a los datos basado en la mezcla entre localizaciones de elementos (URL) y verbos de HTTP para indicar lo que se desea hacer con ese elemento. Eso, agregando un almacén de datos que permita albergar elementos y otras características añadidas, nos dan como resultado CouchDB.

El sistema de CouchDB, además de destacar como base de datos documental, cuya definición, extraída de la Wikipedia, viene a decir:

Permiten la indexación a texto completo, y en líneas generales realizar búsquedas más potentes. Tesaurus es un sistema de índices optimizado para este tipo de bases de datos.

Este sistema está altamente indicado para proyectos del tipo:

  • Buscadores, ya que se pueden almacenar webs y después hacer búsquedas en texto de forma eficiente.
  • Bitácoras, blogs, weblogs…; donde el almacenamiento de artículos o extensos textos, puede ser indizado y manejado para realizar las búsquedas.
  • Almacenes de libros, documentos y otros textos que puedan escribirse, sobre todo en formatos de texto plano, como pueden ser HTML, XML (Docbook, DITA, …), SGML, TXT, LaTeX, …

A esto sumamos que el transporte se realiza mediante HTTP, por la convención establecida mediante REST, y tenemos un sistema fácil de implementar y que soporta la carga que supone transmitir todos los documentos almacenados de una forma eficiente.

Cabe destacar que, aunque sea una base de datos documental y esté basada en el almacenamiento de documentos en campos de texto grandes, también se pueden almacenar otros tipos de datos y crear “tablas” a modo de tener un formato relacional, donde el documento juegue el papel principal, claro.

Erlang y Asterisk… ErlAst

Para permitir una forma más dinámica de programar el plan de marcado (dialplan) de Asterisk, se emplea lo que se conoce como AGI (que viene a ser como el CGI), pero a través de la entrada estándar (stdin) y la salida estándar (stdout).

Como hacer fork dentro de la misma máquina y lanzar los intérpretes de los lenguajes que se suelen usar para AGI (PHP, Perl, Python…) trae consigo una carga considerable a una máquina que puede ya, de por sí, tener bastante carga con Asterisk, la aplicación de dialplan AGI, trae consigo la posibilidad de cambiar el medio de comunicación de entrada y salida estándar, por un socket abierto hacia otro equipo.

Esto trae consigo la ventaja de que, al estar el código de AGI en otra máquina, ya no tiene que lanzarse cada vez una ejecución de intérprete y su consiguiente carga de memoria y tiempo.

Además, otra ventaja, es que el programa externo no tiene que ser lanzado cada vez, sino que puede permanecer en ejecución, con lo que se ahorra aún más.

Prácticamente, todos los lenguajes tienen ya desarrollado un interfaz abierto o libre que maneja lo que se conoce como FastAGI: Java, PHP, Perl, Python… e incluso Erlang.

El lenguaje Erlang me llamó hace poco la atención por ser un lenguaje, al igual que Scala, orientado a la concurrencia, al desarrollo distribuido y tolerante a fallos, por lo que pensé que podría ser un buen lenguaje para desarrollar soluciones que tuviesen que ver con Asterisk, ya que es lo que siempre se busca en las empresas de telecomunicaciones: redundancia, escalabilidad y alta disponibilidad.

El desarrollo de ErlAst está algo abandonado, pero la parte que se refiere a fast_agi es totalmente funcional, por lo que, siguiendo estas líneas, se puede instalar sin problemas en nuestro equipo. Doy por hecho que Erlang se tiene ya instalado y funcionando, al igual que Asterisk. En un sistema Debian o Ubuntu, instalar ambos se hace con apt-get ;-)

Configura ErlAst

Tal y como se dice en la página oficial del proyecto, lo que hay que hacer es bajar la última versión de erlast del repositorio con el siguiente comando:

svn co http://tools.assembla.com/svn/erlast/trunk erlast

NOTA: el código viene con un error que hace que la aplicación de ejemplo no funcione. Tendremos que agregar, antes de trace(true) en el fichero fast_agi.erl el siguiente código:

trace(on) -> trace(true);
trace(off) -> trace(false);

Una vez descargado, tendremos el directorio erlast creado. Como la versión de AMI es aún inestable, pasaremos a compilar y usar solo la parte de fast_agi:

cd erlast
make
cd lib/fast_agi/
make

NOTA: el primer make originará fallos, puesto que AMI no está aún terminado de implementar por el autor.

Escribimos un fichero de configuración dentro del directorio ebin, que se llame fast_agi_conf.config con el siguiente contenido:

[
    {fast_agi, [
        {port,4573},
        {opts, [
            {ip, {192,168,1,1}}
        ]}
    ]}
].

NOTA: configurar de forma correcta la IP que se ponga en este fichero, puesto que si la IP no corresponde con la de nuestro equipo, el sistema devolverá un error y no arrancará.

Por último, probamos que todo funcione, desde dentro del mismo directorio ebin ejecutamos:

$ erl -config fast_agi_conf
Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.5  (abort with ^G)
1> application:start(fast_agi).
ok

Configura Asterisk

En este momento ya tendremos lanzada la aplicación y en escucha a través del puerto 4573, con lo que si configuramos un asterisk con el siguiente extensions.conf, debería de reproducirnos el audio de demo de asterisk (en caso de que esté) y colgar:

exten => 123,1,AGI(agi://192.168.1.1:4573/test_agi/test)
exten => 123,n,HangUp

Lanza una llamada contra asterisk al número 123 y debería de reproducirse el audio.

Conclusión

Visto esto, se puede combinar con el almacenamiento redundante y distribuido de mnesia para conseguir que la llamada a AGI sea tolerante a fallos y se tenga memoria del flujo de llamada, lo cual daría mucho juego y unas aplicaciones mucho más fiables.

Erlang: concurrente, distribuido y en tiempo real

Después de tiempo desarrollando aplicaciones casi exclusivamente en PHP, me encuentro en el problema de que PHP no es, ni mucho menos, un lenguaje de uso general, sino un lenguaje desarrollado y pensado para la creación de aplicaciones web de forma rápida y, de forma controlada, útil y potente para grandes proyectos.

Pero fuera de este entorno, en el background de las grandes empresas donde todo debe de ser escalable, redundante y en alta disponibilidad, y sobre todo cuando las aplicaciones no son para servidores web, usar un lenguaje que no está preparado para el desarrollo deseado, puede conllevar muchos quebraderos de cabeza, e incluso, no alcanzar el objetivo deseado.

Después de revisar varios lenguajes de programación (Java, Python, Ruby…) vi que hay también lenguajes de programación diseñados para tareas concretas y que, saliéndose de la especificación de lenguajes de ámbito general, se especializan en ciertas tareas, tal y como Perl es para el análisis de textos y PHP para la web, encontré esta pequeña joya, Erlang, que es un lenguaje específico para desarrollos que requieran de control de concurrencia, programación distribuida y desarrollos de tiempo real.

El lenguaje en sí ha sido diseñado por Ericsson y dispone de mucha documentación en su sitio web. Su sintaxis no es la típica copia de C que se seguía para Java, C# y PHP, entre otros, sino que tiene un formato nuevo, lo cual hace más lenta la curva de aprendizaje, pero para los programadores que ya hayan usado más de dos lenguajes de programación del tipo Ruby, Python, PHP y/o Perl, hacerse a una nueva sintaxis no será tanto problema.

Iré informando sobre mis avances con este lenguaje, a ver si me deja buen saber de boca ;-)