<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bosque Viejo &#187; programación</title>
	<atom:link href="http://bosqueviejo.net/category/programacion/feed/" rel="self" type="application/rss+xml" />
	<link>http://bosqueviejo.net</link>
	<description>Sitio web sobre programación, software libre, redes, servidores, ofimática... y todo lo relacionado con la informática que nos rodea</description>
	<lastBuildDate>Tue, 08 May 2012 14:40:56 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Juggernaut: invirtiendo el paradigma cliente/servidor</title>
		<link>http://bosqueviejo.net/2012/05/08/juggernaut-invirtiendo-el-paradigma-clienteservidor/</link>
		<comments>http://bosqueviejo.net/2012/05/08/juggernaut-invirtiendo-el-paradigma-clienteservidor/#comments</comments>
		<pubDate>Tue, 08 May 2012 14:40:56 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[desarrollo web]]></category>
		<category><![CDATA[juggernaut]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1371</guid>
		<description><![CDATA[ Juggernaut, además de ser un personaje del universo Marvel, es un servidor escrito en Node.JS, que permite su integración con Ruby on Rails para realizar el intercambio de mensajes en dirección del servidor hacia el navegador.
Este esquema permite al servidor poder enviar mensajes al navegador en cualquier momento, de modo que se mantiene una actualización mucho más precisa que con refrescos esporádicos del navegador web hacia el servidor.
¿Cómo funciona?
Juggernaut, para conseguir esto se basa en el uso de un código en Flash que le permite abrir un socket y mantener la comunicación con el servidor de forma constante. En la parte del cliente, por lo tanto, está el navegador que realiza las peticiones al código de Rails como siempre y, además, el código Flash que abre la comunicación con el servidor de Juggernaut, que le va enviando código en JavaScript que ejecuta para realizar acciones concretas.
En la parte del servidor tenemos también dos elementos bien diferenciados, por un lado tenemos al servidor de Juggernaut ejecutándose en el puerto 5001 (por defecto) y el servidor de Rails ejecutándose en otro puerto (por defecto en desarrollo suele ser el 3000). La comunicación con el servidor de Rails es como siempre en [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/The_Juggernaut-150x150.jpg" alt="" title="The_Juggernaut" width="150" height="150" class="alignleft size-thumbnail wp-image-1372" /> <a href="http://juggernaut.rubyforge.org/">Juggernaut</a>, además de ser un <a href="http://es.wikipedia.org/wiki/Juggernaut_(Marvel_Comics)">personaje del universo Marvel</a>, es un servidor escrito en <a href="/2012/01/03/nodejs-el-servidor-javascript/">Node.JS</a>, que permite su integración con <a href="/2011/10/17/rails-3-1-mejorando-las-vistas/">Ruby on Rails</a> para realizar el intercambio de mensajes en dirección del servidor hacia el navegador.</p>
<p>Este esquema permite al servidor poder enviar mensajes al navegador en cualquier momento, de modo que se mantiene una actualización mucho más precisa que con refrescos esporádicos del navegador web hacia el servidor.</p>
<h3>¿Cómo funciona?</h3>
<p>Juggernaut, para conseguir esto se basa en el uso de un código en Flash que le permite abrir un socket y mantener la comunicación con el servidor de forma constante. En la parte del cliente, por lo tanto, está el navegador que realiza las peticiones al código de Rails como siempre y, además, el código Flash que abre la comunicación con el servidor de Juggernaut, que le va enviando código en JavaScript que ejecuta para realizar acciones concretas.</p>
<p>En la parte del servidor tenemos también dos elementos bien diferenciados, por un lado tenemos al servidor de Juggernaut ejecutándose en el puerto 5001 (por defecto) y el servidor de Rails ejecutándose en otro puerto (por defecto en desarrollo suele ser el 3000). La comunicación con el servidor de Rails es como siempre en protocolo HTTP, mientras que el intercambio de información a través del interfaz de Juggernaut se sucede en formato JSON, enviando información específica a ejecutar en el navegador.</p>
<h3>Instalación</h3>
<p>La verdad es que la instalación no queda nada clara, por lo que voy a explicar el cómo se instala el sistema para tenerlo funcionando en poco tiempo. En principio, necesitamos ejecutar lo siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gem install json
gem install eventmachine
gem install juggernaut
gem install maccman-juggernaut -s http://gems.github.com</pre></div></div>

<p>Tenemos que crear un proyecto Rails. En principio, tendrá que ser una versión anterior a la 3.2, ya que en esa versión se ha eliminado el uso de plugins en favor de las gemas, por lo que, creamos nuestro proyecto Rails y ejecutamos:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">ruby script/plugin install git://github.com/maccman/juggernaut_plugin.git</pre></div></div>

<p>Ahora toca lanzar la parte servidora de Juggernaut, para eso, vamos a generar un fichero de configuración, el sistema nos puede generar uno automáticamente de la siguiente forma:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">juggernaut -g juggernaut.yml</pre></div></div>

<p>Con esto ya tenemos instalado todo el sistema de Juggernaut, y lo básico para poder integrarlo dentro de nuestro proyecto Rails.</p>
<h3>Implementando Juggernaut en Rails</h3>
<p>Introducir Juggernaut en Rails es tan sencillo como crear un nuevo controlador, por ejemplo uno llamado <em>Chat</em>, y escribir el siguiente código en el fichero <tt>chat_controller.rb</tt>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ChatController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> index
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> send_data
    render <span style="color:#ff3333; font-weight:bold;">:juggernaut</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>page<span style="color:#006600; font-weight:bold;">|</span>
        page.<span style="color:#9900CC;">insert_html</span> <span style="color:#ff3333; font-weight:bold;">:top</span>, <span style="color:#996600;">'chat_data'</span>, <span style="color:#996600;">&quot;&lt;li&gt;&lt;strong&gt;#{params['id']}&lt;/strong&gt;: #{h params['chat_input']}&lt;/li&gt;&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    render <span style="color:#ff3333; font-weight:bold;">:nothing</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>En este código tenemos dos entradas, una es el <em>index</em> que lo emplearemos para entrar en la página inicial, y otra es la parte de envío de datos, a la que llamaremos mediante AJAX. El formulario lo montamos de la siguiente forma en el fichero <tt>index.html.erb</tt>:</p>
<pre style="color:#000000;background-color:#f9f9f9; border: #c0c0c0 solid 1px; font-size:12px;">
<b>&lt;html&gt;</b>
<b>&lt;head&gt;</b>
    <b>&lt;title&gt;</b>Chat<b>&lt;/title&gt;</b>
    <b>&lt;%=</b> <span style='color:#000080;'>javascript_include_tag</span> <span style='color:#d40000;'>:defaults</span>, <span style='color:#d40000;'>:juggernaut</span> <b>%&gt;</b>
    <b>&lt;%=</b> juggernaut(<span style='color:#d40000;'>:client_id</span> <span style='color:#ff00ff;'>=&gt;</span> params<span style='color:#ff00ff;'>[</span><span style='color:#d40000;'>:id</span><span style='color:#ff00ff;'>]</span>) <b>%&gt;</b>
<b>&lt;/head&gt;</b>
<b>&lt;body&gt;</b>
    <b>&lt;%=</b> <span style='color:#000080;'>form_remote_tag</span>(
          <span style='color:#d40000;'>:url</span> <span style='color:#ff00ff;'>=&gt;</span> <span style='color:#ff00ff;'>{</span> <span style='color:#d40000;'>:action</span> <span style='color:#ff00ff;'>=&gt;</span> <span style='color:#d40000;'>:send_data</span> <span style='color:#ff00ff;'>}</span>,
          <span style='color:#d40000;'>:complete</span> <span style='color:#ff00ff;'>=&gt;</span> <span style='color:#dd0000;'>&quot;$('chat_input').value = ''&quot;</span> ) <b>%&gt;</b>
    <b>&lt;%=</b> <span style='color:#000080;'>text_field_tag</span>( <span style='color:#dd4a4a;'>'chat_input'</span>, <span style='color:#dd4a4a;'>''</span>, <span style='color:#ff00ff;'>{</span> <span style='color:#d40000;'>:size</span> <span style='color:#ff00ff;'>=&gt;</span> <span style='color:#0000ff;'>20</span>, <span style='color:#d40000;'>:id</span> <span style='color:#ff00ff;'>=&gt;</span> <span style='color:#dd4a4a;'>'chat_input'</span><span style='color:#ff00ff;'>}</span> ) <b>%&gt;</b>
    <b>&lt;%=</b> <span style='color:#000080;'>hidden_field_tag</span>( <span style='color:#dd4a4a;'>'id'</span>, params<span style='color:#ff00ff;'>[</span><span style='color:#d40000;'>:id</span><span style='color:#ff00ff;'>]</span> ) <b>%&gt;</b>
    <b>&lt;%=</b> <span style='color:#000080;'>submit_tag</span> <span style='color:#dd0000;'>&quot;Add&quot;</span> <b>%&gt;</b>
    <b>&lt;/form&gt;</b>
    <b>&lt;ul</b><span style='color:#008000;'> id=</span><span style='color:#aa0000;'>&quot;chat_data&quot;</span><span style='color:#008000;'> style=</span><span style='color:#aa0000;'>&quot;list-style:none&quot;</span><b>&gt;</b>
    <b>&lt;/ul&gt;</b>
<b>&lt;/body&gt;</b>
<b>&lt;/html&gt;</b></pre>
<h3>Lanzando la aplicación</h3>
<p>Lanzamos Rails (ya sea con mongrel, thin o cualquier otro servidor) y Juggernaut. El lanzamiento de Juggernaut lo podemos hacer de la siguiente forma:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">juggernaut -c juggernaut.yml</pre></div></div>

<p>Ahora vamos al navegador, abrimos dos navegadores:</p>
<ul>
<li><a href="http://localhost:3000/chat/index/yo">http://localhost:3000/chat/index/yo</a></li>
<li><a href="http://localhost:3000/chat/index/tu">http://localhost:3000/chat/index/tu</a></li>
</ul>
<p>Si vamos escribiendo en una ventana, veremos como van apareciendo los textos en ambas, algo como esto:</p>
<p><img src="http://bosqueviejo.net/wp-content/uploads/chat_juggernaut.png" alt="" title="chat_juggernaut" width="709" height="283" class="aligncenter size-full wp-image-1392" /></p>
<p>Con lo que comprobamos que el sistema funciona correctamente.</p>
<h3>Algunas pegas</h3>
<p>Como hemos visto desde el principio, la comunicación del navegador se realiza a través de un puerto que no es el 80, típico del protocolo HTTP, y que tampoco es protocolo HTTP lo que transita por ese puerto, por lo que, en instalaciones con acceso a Internet restringido, es posible que este sistema no funcione correctamente.</p>
<p>Además, se suma el problema de que el puerto 5001 debe de mantenerse abierto hacia Internet, si no configuramos con suficiente seguridad, a través del fichero <tt>juggernaut.yml</tt> el sistema, podemos encontrarnos un verdadero agujero de seguridad&#8230; ya depende de para qué usemos Juggernaut, pero teniendo en cuenta de que ejecuta código JavaScript en el cliente, podría ser algo nocivo.</p>
<h3>Conclusiones</h3>
<p>Esta aproximación al sistema de Juggernaut ha sido bastante interesante para descubrir una forma de realizar este tipo de comunicaciones entre cliente y servidor de forma inversa, es decir, que el servidor pueda enviar información al cliente sin que el cliente la solicite. No obstante, los navegadores actuales implementan un sistema denominado <em>websocket</em> que tenderá a sustituir estos mecanismos artesanos de una forma más estándar y frameworks como ChicagoBoss ya lo implementan de forma nativa. El futuro nos mostrará los caminos que se van tomando, de momento, Juggernaut es una muy buena solución para todos los navegadores web actuales.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/05/08/juggernaut-invirtiendo-el-paradigma-clienteservidor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Estructura Lider/Trabajador en Erlang</title>
		<link>http://bosqueviejo.net/2012/05/07/estructura-lider-trabajador-en-erlang/</link>
		<comments>http://bosqueviejo.net/2012/05/07/estructura-lider-trabajador-en-erlang/#comments</comments>
		<pubDate>Mon, 07 May 2012 11:22:51 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[gen_leader]]></category>
		<category><![CDATA[lider/trabajador]]></category>
		<category><![CDATA[maestro/esclavo]]></category>
		<category><![CDATA[otp]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1359</guid>
		<description><![CDATA[ Erlang es muy bueno para programación distribuida, y paralela, y concurrente, así mismo se hace muy simple la creación de servidores, tal y como he mostrado en entradas anteriores (servidor UDP y servidor TCP), pero nos queda una tipo de comportamiento que es algo complejo llevar a la práctica. Me refiero al paradigma de Maestro-Esclavo.
La teoría
El paradigma Maestro-Esclavo se basa en que, para acceder a un recurso que está disponible solo desde un punto o solo para un servicio, ya sea por que su acceso es crítico en concurrencia o porque solo se pueda acceder desde un único punto cada vez, se hace necesaria una estructura en la que un único punto sea el responsable de ese acceso, quedando todos los demás supeditados a este.
Esto genera igualmente un problema de cuello de botella, pero la misión no es distribuir, en este caso, para ganar más potencia de procesamiento, sino conseguir: una mayor alta disponibilidad para un recurso accesible solo desde un punto cada vez.
En la terminología de Erlang, la nomenclatura empleada es líder (leader) para referirse al maestro elegido cada vez, y trabajador (worker) para referirse a los esclavos. Esto es así por dos sutiles diferencias que existen entre [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/lider-150x150.jpg" alt="" title="lider" width="150" height="150" class="alignleft size-thumbnail wp-image-1360" /> Erlang es muy bueno para programación distribuida, y paralela, y concurrente, así mismo se hace muy simple la creación de servidores, tal y como he mostrado en entradas anteriores (<a href="/2012/03/21/erlang-servidores-udp/">servidor UDP</a> y <a href="/2012/04/09/erlang-servidores-concurrentes-tcp/">servidor TCP</a>), pero nos queda una tipo de comportamiento que es algo complejo llevar a la práctica. Me refiero al paradigma de Maestro-Esclavo.<span id="more-1359"></span></p>
<h3>La teoría</h3>
<p>El paradigma Maestro-Esclavo se basa en que, para acceder a un recurso que está disponible solo desde un punto o solo para un servicio, ya sea por que su acceso es crítico en concurrencia o porque solo se pueda acceder desde un único punto cada vez, se hace necesaria una estructura en la que un único punto sea el responsable de ese acceso, quedando todos los demás supeditados a este.</p>
<p>Esto genera igualmente un problema de cuello de botella, pero la misión no es distribuir, en este caso, para ganar más potencia de procesamiento, sino conseguir: una mayor alta disponibilidad para un recurso accesible solo desde un punto cada vez.</p>
<p>En la terminología de Erlang, la nomenclatura empleada es <em>líder</em> (leader) para referirse al maestro elegido cada vez, y <em>trabajador</em> (worker) para referirse a los esclavos. Esto es así por dos sutiles diferencias que existen entre el modelo clásico de maestro-esclavo frente a este de lider-trabajador:</p>
<ul>
<li>El maestro es siempre uno y se carga con las tareas de replicación y de escritura, el líder, sin embargo, se carga con todas las tareas y no replica nada entre sus trabajadores.</li>
<li>El esclavo se encarga de las tareas más frecuentes, en su caso, las lecturas, sin pedir nada al maestro. Si le llega una escritura puede remitirla a su maestro o ignorarla, depende de la implementación. El trabajador, sin embargo, delega todos los trabajos al líder.</li>
<li>Cuando un maestro <em>muere</em>, los esclavos quedan atendiendo lecturas, pero el sistema de escritura queda sin servicio, a menos que haya algún mecanismo que permita, por alta disponibilidad, levantar a otro maestro, pero no es la base del paradigma. Cuando un líder <em>muere</em>, en cambio, de entre los trabajadores se elige a un nuevo líder, que se encarga de las peticiones. El esquema está pensado en sí para tener una alta disponibilidad.</li>
</ul>
<p>Aunque es un comportamiento bastante básico, aún no se ha introducido en la base de Erlang, ya que sus algoritmos de elección han sufrido cambios, incluso hasta hace pocos meses. Supongo que incluso aún habrá algún que otro cambio más, por lo que conviene mantenerse al día. El repositorio oficial (de momento) es <a href="https://github.com/abecciu/gen_leader_revival">este de github, gen_leader_revival de abecciu</a>.</p>
<p>Los autores de la base son Andrew Thompson, Dave Fayram, Hans Svensson y Ulf Wiger.</p>
<h3>La implementación</h3>
<p>El código podemos descargarlo del repositorio indicado anteriormente, solo necesitaremos el código de <a href="https://raw.github.com/abecciu/gen_leader_revival/master/src/gen_leader.erl">gen_leader.erl</a> y el código de <a href="https://raw.github.com/abecciu/gen_leader_revival/master/examples/skeleton.erl">skeleton.erl</a>.</p>
<p>La plantilla nos da lo básico para que el <tt>gen_leader</tt> funcione. Si compilamos ambas y lanzamos desde una consola el <tt>skeleton</tt>, podemos ver que funciona correctamente. Es más, vamos a modificarlo muy poquito agregando solo impresiones por pantalla para saber en qué momento se ejecuta cada uno:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">elected</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Election</span><span style="color: #6bb810;">,</span> undefined<span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Synch</span> <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;no one elected? ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Synch</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
&nbsp;
<span style="color: #ff3c00;">elected</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Election</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Node</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;elected node [~p]: ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Node</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>reply<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">surrendered</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Synch</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;surrendered (~p): ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Synch</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">handle_leader_call</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Request</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_From</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;leader_call (~p): ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>gen_leader:<span style="color: #006600;">leader_</span><span style="color: #fa6fff;">node</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Request</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>reply<span style="color: #6bb810;">,</span> ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">from_leader</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Synch</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;from_leader (~p): ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>gen_leader:<span style="color: #006600;">leader_</span><span style="color: #fa6fff;">node</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Synch</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">handle_DOWN</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Node</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;DOWN (~p): ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Node</span><span style="color: #6bb810;">,</span> gen_leader:<span style="color: #006600;">leader_</span><span style="color: #fa6fff;">node</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Election</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>El código modificado es llamado como <em>callback</em> cuando se suceden las siguientes situaciones:</p>
<ul>
<li><tt>elected</tt> (con nodo <tt>undefined</tt>), es llamada cuando el nodo es elegido para ser líder, si la variable de <tt>Nodo</tt> no es <tt>undefined</tt>, entonces es llamado cuando un nuevo trabajador se ha unido al líder.</li>
<li><tt>surrendered</tt>, llamada en trabajadores cuando un líder ha sido elegido, o cuando un nuevo nodo entra en el clúster, y se decide de nuevo quién es el líder, siendo llamado <tt>elected</tt> en el líder elegido y <tt>surrendered</tt> en el nuevo trabajador.</li>
<li><tt>handle_leader_call</tt>, esta llamada la realiza quien necesita algo del cluster, o cualquiera de los trabajadores al líder, pero en esencia, solo se proces en el líder.</li>
<li><tt>from_leader</tt>, mensajes que se emiten desde el líder hacia los trabajadores. Si la devolución de <tt>handle_leader_call</tt> es <tt>{reply, Reply, Broadcast, State}</tt>, se envía el mensaje de <em>Broadcast</em> a todos los trabajadores, con lo que pueden hacer alguna sincronización con su estado interno o realizar la acción que se requiera.</li>
<li><tt>handle_DOWN</tt>, mensaje de caída recibida por el líder de los nodos que han caído. Cuando cae el líder, un nuevo líder es elegido y se le envía la señal de caída del nodo del antiguo líder.</li>
</ul>
<p>Teniendo estas características en cuenta, podemos ejecutar el código y ver cómo se comporta:</p>
<p>En <strong>lider1@bosqueviejo</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(lider1@bosqueviejo)1&gt; {ok, Pid} = datos:start_link(['lider1@bosqueviejo', 'lider2@bosqueviejo']).
no one elected? {election,&lt;0.55.0&gt;,none,datos,lider1@bosqueviejo,
                          [lider1@bosqueviejo,lider2@bosqueviejo],
                          [],
                          [lider2@bosqueviejo],
                          [],[],none,norm,
                          {1,6,0},
                          [],[],5000,
                          {interval,#Ref&lt;0.0.0.49&gt;},
                          lider2@bosqueviejo,6,1,sender}
{ok,&lt;0.55.0&gt;}</pre></div></div>

<p>Ahora levantamos en <strong>lider2@bosqueviejo</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(lider2@bosqueviejo)1&gt; {ok, Pid} = datos:start_link(['lider1@bosqueviejo', 'lider2@bosqueviejo']).
{ok,&lt;0.55.0&gt;}
surrendered ([]): {election,&lt;6327.55.0&gt;,none,datos,lider1@bosqueviejo,
                            [lider1@bosqueviejo,lider2@bosqueviejo],
                            [],[],
                            [{lider1@bosqueviejo,lider1@bosqueviejo},
                             {#Ref&lt;0.0.0.59&gt;,lider1@bosqueviejo},
                             {#Ref&lt;0.0.0.57&gt;,lider1@bosqueviejo}],
                            [],none,norm,
                            {1,6,0},
                            [],[],5000,undefined,undefined,5,1,sender}</pre></div></div>

<p>En <strong>lider1@bosqueviejo</strong> se sucede el siguiente mensaje al levantar al <strong>lider2@bosqueviejo</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">elected node [lider2@bosqueviejo]: {election,&lt;0.55.0&gt;,none,datos,
                                       lider1@bosqueviejo,
                                       [lider1@bosqueviejo,lider2@bosqueviejo],
                                       [],[],
                                       [{#Ref&lt;0.0.0.74&gt;,lider2@bosqueviejo}],
                                       [],none,norm,
                                       {1,6,0},
                                       [],[],5000,
                                       {interval,#Ref&lt;0.0.0.49&gt;},
                                       lider2@bosqueviejo,6,1,sender}</pre></div></div>

<p>Ahora en <strong>lider1@bosqueviejo</strong> enviamos un mensaje:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(lider1@bosqueviejo)2&gt; gen_leader:leader_call(Pid, &quot;hola&quot;).
leader_call (lider1@bosqueviejo): &quot;hola&quot;
ok</pre></div></div>

<p>Y lo que pasaba al mismo tiempo en <strong>lider2@bosqueviejo</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">from_leader (lider1@bosqueviejo): [118,117,101,115,116,114,111,32,108,105,100,
                                   101,114,32,100,105,99,101,58,32,&quot;hola&quot;,
                                   &quot;\n&quot;]</pre></div></div>

<p>En caso de que salgamos de la consola del <strong>lider1@bosqueviejo</strong> vemos lo siguiente en <strong>lider2@bosqueviejo</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">no one elected? {election,&lt;0.55.0&gt;,&lt;6327.55.0&gt;,datos,lider2@bosqueviejo,
                          [lider1@bosqueviejo,lider2@bosqueviejo],
                          [],
                          [lider1@bosqueviejo],
                          [{#Ref&lt;0.0.0.59&gt;,lider1@bosqueviejo},
                           {#Ref&lt;0.0.0.57&gt;,lider1@bosqueviejo}],
                          [],none,norm,
                          {2,5,1},
                          [],[],5000,
                          {interval,#Ref&lt;0.0.0.75&gt;},
                          lider2@bosqueviejo,5,2,sender}
DOWN (lider1@bosqueviejo): lider2@bosqueviejo</pre></div></div>

<p>Es decir, se elige a un nuevo líder y se envía el mensaje de caída del líder.</p>
<h3>Conclusiones</h3>
<p>Este esquema es bastante útil ya que simplifica el problema de tener varios servidores, por ejemplo, y recursos que solo pueden estar disponibles en un solo servidor cada vez. Por ejemplo, el acceso a un recurso propietario que solo nos da una licencia de uso, el acceso con control de concurrencia a un recurso.</p>
<p>Su interfaz de broadcast, permite que el sistema pueda recibir peticiones de lectura y escritura, haciendo que su <em>broadcast</em> deje la información en cada worker para, en caso de que cayese el líder, puedan seguir funcionando sin problema alguno.</p>
<p>Realmente, otro elemento más para facilitar la creación de sistemas servidores de alta disponibilidad en Erlang.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/05/07/estructura-lider-trabajador-en-erlang/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go: El lenguaje de Google</title>
		<link>http://bosqueviejo.net/2012/04/10/go-el-lenguaje-de-google/</link>
		<comments>http://bosqueviejo.net/2012/04/10/go-el-lenguaje-de-google/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 17:32:54 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[go]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[lenguajes]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1314</guid>
		<description><![CDATA[ Hace un par de años que escuché que Google trabajaba en un lenguaje, y hace poco que ya había visto la luz una versión estable, la primera.
Hay personas que me han comentado que Go era parecido a Erlang, que Go hacía concurrencia de forma muy simple, y que Go es un lenguaje muy a tener en cuenta y presente, sobretodo en terreno de concurrencia y escalabilidad. Hoy le he dedicado un par de horas a revisar la documentación y a programar un poco y ver cómo se programa en Go, las potencias que tiene el lenguaje según sus creadores (y lo que han podido introducir a lo largo del tutorial y el manual).
En 2007, un diseño inicial de Go fue comenzado por Robert Griesemer, junto a Rob Pike (creador del lenguaje Limbo) y Ken Thompson (uno de los creadores del lenguaje C y Unix), todos ellos bajo el seno de Google, donde los tres trabajan actualmente, por lo que, de momento, por su historia, promete.
Revisión del lenguaje
En principio, Go es un lenguaje tipado y fuertemente tipado. Tiene auto-detección de tipos para no tener que escribir mucho y han organizado su declaración de modo que resulta un poco extraño para [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/Go-Mascota-de-Go-Gordon-150x150.jpg" alt="" title="Go-Mascota-de-Go-Gordon" width="150" height="150" class="alignleft size-thumbnail wp-image-1315" /> Hace un par de años que escuché que Google trabajaba en un lenguaje, y hace poco que ya había visto la luz una <a href="http://blog.golang.org/2012/03/go-version-1-is-released.html">versión estable, la primera</a>.</p>
<p>Hay personas que me han comentado que Go era parecido a Erlang, que Go hacía concurrencia de forma muy simple, y que Go es un lenguaje muy a tener en cuenta y presente, sobretodo en terreno de concurrencia y escalabilidad. Hoy le he dedicado un par de horas a revisar la documentación y a programar un poco y ver cómo se programa en Go, las potencias que tiene el lenguaje según sus creadores (y lo que han podido introducir a lo largo del tutorial y el manual).</p>
<p>En 2007, un diseño inicial de Go fue comenzado por Robert Griesemer, junto a Rob Pike (creador del lenguaje Limbo) y Ken Thompson (uno de los creadores del lenguaje C y Unix), todos ellos bajo el seno de Google, donde los tres trabajan actualmente, por lo que, de momento, por su historia, promete.</p>
<h3>Revisión del lenguaje</h3>
<p>En principio, Go es un lenguaje tipado y fuertemente tipado. Tiene auto-detección de tipos para no tener que escribir mucho y han organizado su declaración de modo que resulta un poco extraño para quien haya programado en C y Java, por ejemplo. Mientras que un código en estos lenguajes declara el tipo y modificadores para después indicar el nombre de la variable, Go lo hace al revés. Se indica primero el nombre de las variables y después el tipo. Además, el tipo puede tomarse de forma intrínseca si se hace una inicialización con un valor. Por ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="unknown" style="font-family:monospace;">var x int  // declaración simple
var y, z int  // declaración múltiple, ambas serán int
var a := 1  // declaración intrínseca a int
var a, b := 1, 2 // declaración intrínseca de a y b a int</pre></div></div>

<p>En este aspecto, recuerda bastante a Python, pudiendo hacer asignación múltiple en una misma línea. La palabra <tt>var</tt> es necesaria en la declaración de las variables de modo global, y solo opcional dentro de las funciones. Un dato de tipo intrínseco dentro de las funciones, a menos que se emplee <tt>var</tt>, debe de indicarse con el operador :=</p>
<p>La declaración de funciones se realiza con la palabra clave <tt>func</tt>, pudiendo aceptar parámetros tipados de la misma forma que la declaración de variables. El retorno, al igual que la asignación, se realiza de modo que se puedan retornar varios valores, igualmente, otro parecido más a Python en este sentido:</p>

<div class="wp_syntax"><div class="code"><pre class="unknown" style="font-family:monospace;">func add( x, y int ) int {
    return x + y
}</pre></div></div>

<p>En parecido con C, para que el código sea ejecutado, debe de existir una función <em>main</em>.</p>
<p>Como estructuras de control, tenemos <tt>if</tt>, <tt>for</tt> y <tt>switch</tt>. El bucle <em>while</em> se puede simular a través del uso simplificado de <tt>for</tt>, que permite eliminar la parte de inicialización y actualización para realizar son la condición de bucle. Igualmente, si no se indican ninguna de las tres, se realiza un bucle infinito.</p>

<div class="wp_syntax"><div class="code"><pre class="unknown" style="font-family:monospace;">for i := 1; i&lt;10; i++ {
    // bucle for normal
}
&nbsp;
for i &lt; 10 {
    // simulación de while
}
&nbsp;
for {
    // bucle infinito
}</pre></div></div>

<p>Las estructuras <tt>if</tt> permiten el uso de la parte de inicialización, como si se tratase de un bucle <tt>for</tt>, y las estructuras <tt>switch</tt> permiten declarar comparadores, no solo valores estáticos como en Java, C, PHP y otros, además de también el bloque de inicialización como <tt>if</tt>:</p>

<div class="wp_syntax"><div class="code"><pre class="unknown" style="font-family:monospace;">if i == 10 {
    // if normal
}
&nbsp;
if i=10; i==10 {
    // if con inicialización
}
&nbsp;
switch i=10; i {
    case 1: // si es 1
    case 2: // si es 2
    case 10: // aqui entra
    default: // por defecto
}
&nbsp;
switch {
    case i == 1: // si es 1
    case i == 2: // si es 2
    case i &gt; 3: // aqui entra
    default: // por defecto
}</pre></div></div>

<p>La organización de las estructuras de datos se puede hacer mediante <tt>struct</tt>, al igual que en C, e incluso se pueden definir funciones que trabajen como si uno de sus parámetros intrínsecos fuese un <tt>struct</tt>. Con esto se puede simular el uso de los métodos, pero queda muy lejos de lo que respecta a la programación orientada a objetos.</p>
<p>Se pueden ver más ejemplos en <a href="http://tour.golang.org/">tutorial de Go (en inglés)</a>.</p>
<h3>Potencias del lenguaje</h3>
<p>Revisándolo a fondo, veo que la tendencia de los lenguajes de tipado estático comienza a estar de moda, tienen sus ventajas ya que permiten cazar fallos en tiempo de compilación (cuando no hay inferencia de tipos, claro). En este caso esa cualidad es bastante evidente, así como que el código pueda compilarse de forma nativa como hace también Opa.</p>
<p>La concurrencia que emplea Go se parece bastante a Erlang en base en que es por paso de mensajes. La única diferencia radica en que el buzón para el paso de mensajes se debe de crear. Go nomina sus buzones como canales de comunicación. Un símil muy aproximado a los sockets Unix, ya que se establecen como recursos independientes y se pueden emplear en cualquier proceso y en cualquier momento.</p>
<h3>Conclusiones</h3>
<p>El lenguaje Go es un lenguaje que ha nacido con un propósito claro, según sus objetivos entre los que se encuentran: seguridad (de tipos y de memoria), buen soporte de concurrencia y comunicación, eficiencia en la recolección de basura (sin latencias) y alta velocidad de compilación.</p>
<p>Viniendo de dos de los trabajadores de los laboratorios Bell que contribuyeron a lenguajes como Limbo, C, BPEL, etc. y estando en el seno de Google, el futuro de este lenguaje se ve muy prometedor.</p>
<p>Este lenguaje permite la programación orientada a la concurrencia o modelo actor, con lo que, la orientación a objetos, realmente, no es una característica que se eche en falta, ni mucho menos, siempre teniendo presente que el paradigma de programación al que se orienta no son los objetos, en su núcleo central, sino los procesos (o hilos).</p>
<p>Cabe destacar que el uso de la memoria compartida es un hecho ya que el comando <tt>go</tt> lo que hace es lanzar, como dice el tutorial <em>goroutines</em>, que a nivel interno son hilos, por lo que comparte el mismo <em>heap</em> de memoria y puede llegar a ser un problema en el uso de la concurrencia y el modelo actor propiamente dicho.</p>
<p>Por otro lado, carece de estructuras que faciliten el uso de monitores de hilos a modo de que cuando uno muera se notifique este hecho a otro y poder construir estructuras como las de los supervisores.</p>
<p>Veremos como va progresando a lo largo de las siguientes liberaciones, de momento son buenos pasos los que ha dado el pequeño, y con la promesa de Google de mantener la sintaxis y compatibilidad en sus futuras versiones, es una seguridad de cara a programar y no tener que refactorizar al cambiar a una nueva versión.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/04/10/go-el-lenguaje-de-google/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Erlang: Servidores Concurrentes TCP</title>
		<link>http://bosqueviejo.net/2012/04/09/erlang-servidores-concurrentes-tcp/</link>
		<comments>http://bosqueviejo.net/2012/04/09/erlang-servidores-concurrentes-tcp/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 10:43:10 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[gen_server]]></category>
		<category><![CDATA[gen_tcp]]></category>
		<category><![CDATA[otp]]></category>
		<category><![CDATA[programación concurrente]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1270</guid>
		<description><![CDATA[ Para la programación de elementos que requieran concurrencia, Erlang, es una de las mejores elecciones que se puede tomar. El hecho de construir servidores UDP con los mecanismos que nos ofrece OTP es algo trivial, muy simple de conseguir, tal y como se puede ver en este otro artículo, pero la cosa se complica, cuando lo que queremos obtener es una conexión, o un conjunto de conexiones concurrentes para TCP.
Para comenzar, vamos a poner de nuevo de manifiesto la plantilla del gen_server, si se quieren tener más referencias sobre el gen_server se puede consultar este otro artículo, o de forma más extensa en este artículo del Blog Aprendiendo Erlang.
Por lo tanto, la estructura de un código con gen_server es la siguiente:

-module&#40;server&#41;.
-author&#40;'bombadil@bosqueviejo.net'&#41;.
&#160;
-behaviour&#40;gen_server&#41;.
&#160;
-define&#40;SERVER, ?MODULE&#41;.
&#160;
-export&#40;&#91;start_link/0&#93;&#41;.
-export&#40;&#91;init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3&#93;&#41;.
&#160;
-record&#40;state, &#123;&#125;&#41;.
&#160;
start_link&#40;&#41; -&#62;
    gen_server:start_link&#40;&#123;local, ?SERVER&#125;, ?MODULE, &#91;&#93;, &#91;&#93;&#41;.
&#160;
init&#40;&#91;&#93;&#41; -&#62;
    &#123;ok, #state&#123;&#125;&#125;.
&#160;
handle_call&#40;_Request, _From, State&#41; -&#62;
    Reply = ok,
    &#123;reply, Reply, State&#125;.
&#160;
handle_cast&#40;_Msg, State&#41; -&#62;
    &#123;noreply, State&#125;.
&#160;
handle_info&#40;_Info, State&#41; -&#62;
    &#123;noreply, State&#125;.
&#160;
terminate&#40;_Reason, _State&#41; -&#62;
    ok.
&#160;
code_change&#40;_OldVsn, State, _Extra&#41; -&#62;
    &#123;ok, State&#125;.

Agregando conexiones TCP
TCP, a diferencia de [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/telefonistas-150x150.jpg" alt="" title="telefonistas" width="150" height="150" class="alignleft size-thumbnail wp-image-1304" /> Para la programación de elementos que requieran concurrencia, Erlang, es una de las mejores elecciones que se puede tomar. El hecho de construir servidores UDP con los mecanismos que nos ofrece OTP es algo trivial, muy simple de conseguir, tal y como se puede ver en <a href="/2012/03/21/erlang-servidores-udp/">este otro artículo</a>, pero la cosa se complica, cuando lo que queremos obtener es una conexión, o un conjunto de conexiones concurrentes para TCP.</p>
<p>Para comenzar, vamos a poner de nuevo de manifiesto la plantilla del <tt>gen_server</tt>, si se quieren tener más referencias sobre el <tt>gen_server</tt> se puede consultar <a href="/2012/03/21/erlang-servidores-udp/">este otro artículo</a>, o de forma más extensa en <a href="http://aprendiendo-erlang.blogspot.com.es/2011/11/genserver-servidor-generico.html">este artículo del Blog Aprendiendo Erlang</a>.</p>
<p>Por lo tanto, la estructura de un código con <tt>gen_server</tt> es la siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>server<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">author</span><span style="color: #109ab8;">&#40;</span><span style="">'bombadil@bosqueviejo.net'</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">behaviour</span><span style="color: #109ab8;">&#40;</span>gen_server<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">SERVER</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">MODULE</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>start_link<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>init<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> handle_call<span style="color: #014ea4;">/</span><span style="color: #ff9600;">3</span><span style="color: #6bb810;">,</span> handle_cast<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> handle_info<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span>
         terminate<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> code_change<span style="color: #014ea4;">/</span><span style="color: #ff9600;">3</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">record</span><span style="color: #109ab8;">&#40;</span><span style="color: #d400ed;">state</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
start_<span style="color: #fa6fff;">link</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">gen_server</span>:<span style="color: #006600;">start_</span><span style="color: #fa6fff;">link</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span>local<span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">SERVER</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">MODULE</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">init</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> #<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">handle_call</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Request</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_From</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Reply</span> <span style="color: #014ea4;">=</span> ok<span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>reply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Reply</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">handle_cast</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Msg</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">handle_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Info</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">terminate</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Reason</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #006600;">ok</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">code_change</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_OldVsn</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Extra</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<h3>Agregando conexiones TCP</h3>
<p>TCP, a diferencia de UDP, necesita formalizar que está escuchando en un nodo, y aceptar cada petición entrante para mantener una comunicación bilateral. En este caso, el <tt>init</tt> se complica. Debemos de establecer la escucha del puerto y esto requiere de que pasemos algunos parámetro y opciones:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">record</span><span style="color: #109ab8;">&#40;</span><span style="color: #d400ed;">state</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>lsocket<span style="color: #6bb810;">,</span> socket<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">init</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Opts</span> <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#91;</span><span style="color: #fa6fff;">binary</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>packet<span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>active<span style="color: #6bb810;">,</span> true<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">gen_tcp</span>:<span style="color: #ff3c00;">listen</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff9600;">5000</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Opts</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">LSocket</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> #<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span>lsocket <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">LSocket</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
        <span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span>stop<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Para esto, tendremos que agregar el parámetro <tt>lsocket</tt> y <tt>socket</tt> al registro de estado.</p>
<p>La función <tt>init</tt> se encarga de establecer la escucha en el puerto 5000, de forma activa. Para más opciones se puede revisar tanto la documentación de <a href="http://www.erlang.org/doc/man/gen_tcp.html">gen_tcp</a>, como las opciones específicas disponibles en el paquete <a href="http://www.erlang.org/doc/man/inet.html#setopts-2">inet a través de setops</a>.</p>
<p>Como se puede ver, en caso de que la escucha se establezca de forma apropiada, hay un <tt>timeout</tt> configurado a cero, por lo que, se llamará al <em>callback</em> de <tt>handle_info</tt>, con el parámetro <tt>timeout</tt>. En ese punto, es donde tenemos que agregar la parte del servidor TCP en la que se espera por una conexión entrante para poder atenderla. La función, por tanto, sería:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">handle_info</span><span style="color: #109ab8;">&#40;</span>timeout<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #014ea4;">=</span>#<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span>lsocket<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">LSocket</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">gen_tcp</span>:<span style="color: #ff3c00;">accept</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">LSocket</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span>socket<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
&nbsp;
<span style="color: #ff3c00;">handle_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Info</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #014ea4;">=</span>#<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span>socket<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Info</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">gen_tcp</span>:<span style="color: #ff3c00;">send</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #ff4e18;">io_lib</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">date</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><span style="color: #fa6fff;">time</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">gen_tcp</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>El programa es algo simple, ya que acepta la conexión, espera una transmisión y responde enviando la fecha y hora y cierra la conexión. Podemos probarlo de la siguiente forma:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ nc localhost 5000
hola
{{2012,4,4},{20,5,49}}</pre></div></div>

<h3>Y ahora&#8230; la concurrencia</h3>
<p>Como puedes observar, mientras tienes abierta la primera conexión, la segunda no se establece porque el sistema está ocupado con la primera petición. Esto conlleva un cuello de botella, ya que la concurrencia es nula.</p>
<p>Para conseguir ampliar la concurrencia, desde el primer servidor, el proceso que tiene en escucha el puerto, debe de lanzar un proceso, un nuevo servidor para atender cada petición de forma independiente.</p>
<p>Para esto necesitamos crear otro nuevo <em>gen_server</em>, pero con unas características diferentes, ya que no se mantendrá a la espera de conexiones entrantes, sino que será para manejar una conexión activa.</p>
<p>El módulo <tt>gen_tcp</tt> nos ayuda en esta tarea, ya que cada mensaje entrante lo recibimos a través de <tt>handle_info</tt> en el proceso padre, como habíamos visto antes, y esto debemos de redireccionarlo hacia el proceso hijo que creemos. En principio, copiando la estructura de <tt>gen_server</tt> de nuevo y llamándola <tt>request</tt>, agregamos un par de cambios como el siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">start_<span style="color: #fa6fff;">link</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">gen_server</span>:<span style="color: #006600;">start_</span><span style="color: #fa6fff;">link</span><span style="color: #109ab8;">&#40;</span>?<span style="color: #6941fd;">MODULE</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">gen_tcp</span>:<span style="color: #006600;">controlling_</span><span style="color: #fa6fff;">process</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">inet</span>:<span style="color: #ff3c00;">setopts</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>active<span style="color: #6bb810;">,</span> once<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Esta forma de lanzar el <tt>gen_server</tt>, hace que el proceso no tenga un nombre asociado, por lo que se pueden lanzar tantos como queramos o necesitemos. Para el <tt>gen_tcp</tt>, indicamos que el proceso que atenderá las peticiones de ese socket será el que se acaba de crear, y se le indica que puede enviar una petición.</p>
<p>La función de inicialización tendrá esta forma:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">record</span><span style="color: #109ab8;">&#40;</span><span style="color: #d400ed;">state</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>socket<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">init</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> #<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span>socket<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>En el módulo <tt>server</tt> podemos eliminar la parte de gestión de la petición (la parte de <tt>handle_info</tt> que se refiere estrictamente a la gestión de la petición) y dejar solo la parte de la aceptación de la petición de esta forma:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">handle_info</span><span style="color: #109ab8;">&#40;</span>timeout<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #014ea4;">=</span>#<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span>lsocket<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">LSocket</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">gen_tcp</span>:<span style="color: #ff3c00;">accept</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">LSocket</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    request:<span style="color: #006600;">start_</span><span style="color: #fa6fff;">link</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>En el nuevo módulo <tt>request</tt>, agregamos la parte de código que se encarga de realizar la contestación:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">handle_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Info</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #014ea4;">=</span>#<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span>socket<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Info</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">gen_tcp</span>:<span style="color: #ff3c00;">send</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #ff4e18;">io_lib</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">date</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><span style="color: #fa6fff;">time</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">gen_tcp</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>stop<span style="color: #6bb810;">,</span> normal<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>En este caso, cuando <tt>gen_tcp</tt> envía un mensaje desde el cliente al servidor, este mensaje disparará la ejecución de esta función, imprimirá por pantalla el mensaje recibido, contestará de forma fija con la fecha y hora actual, cerrará la conexión con el cliente y detendrá la ejecución del proceso.</p>
<h3>Algunas pruebas</h3>
<p>Si ejecutamos en una máquina virtual de Erlang el servidor, y abrimos dos consolas o tres o más con el siguiente comando:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ nc localhost 5000</pre></div></div>

<p>Veremos que todas y cada una de las consolas obtienen conexión y quedan en el proceso hijo a la espera de un mensaje que envíes. Puedes poner el texto que quieras y presionar el retorno de carro. Volviendo a la consola de Erlang, se verá el mensaje escrito en cada una de las consolas.</p>
<p>Si modificamos el código para que acepte paquetes de tipo <em>http</em> y procesamos una respuesta válida, podemos probar la carga a través de programas como <a href="https://github.com/wg/wrk">wrk</a> o <a href="">ab</a>. En mis pruebas, he conseguido:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ ab -n 10000 -c 50 http://127.0.0.1:5000/
[...]
Concurrency Level:      50
Time taken for tests:   0.885 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      760000 bytes
HTML transferred:       110000 bytes
Requests per second:    11303.38 [#/sec] (mean)
Time per request:       4.423 [ms] (mean)
Time per request:       0.088 [ms] (mean, across all concurrent requests)
Transfer rate:          838.92 [Kbytes/sec] received</pre></div></div>

<p>Una tasa de unas 11 mil peticiones por segundo. Nada mal.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/04/09/erlang-servidores-concurrentes-tcp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erlang: Servidores UDP</title>
		<link>http://bosqueviejo.net/2012/03/21/erlang-servidores-udp/</link>
		<comments>http://bosqueviejo.net/2012/03/21/erlang-servidores-udp/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 10:03:23 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[netcat]]></category>
		<category><![CDATA[otp]]></category>
		<category><![CDATA[programación concurrente]]></category>
		<category><![CDATA[udp]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1274</guid>
		<description><![CDATA[ Una de las grandes potencias de Erlang es su capacidad para construir servidores. A través de OTP, esta tarea se convierte en algo tan sencillo, que asombra ver con qué pocas líneas de código se crea un servidor.
En este caso vamos a montar un servidor UDP. Esto lo revisé en su día porque estuve realizando un pequeño servidor para el protocolo syslog, de lo que resultó este servidor, que permite pasar a través de un manejador de eventos (gen_event) los mensajes de syslog recibidos a través del puerto 514 en formato UDP.
En principio, comentaré un poco la estructura del comportamiento (behaviour) de Erlang/OTP que emplearemos: gen_server.
Empleando los gen_server
El gen_server es el comportamiento más básico que se encuentra disponible en OTP, ya que sobre él se construyen otros como gen_fsm. Este comportamiento específico se fundamenta en la recepción de mensajes y su manejo a través de unos callbacks, de modo que tenemos tres tipos de mensajes que podemos procesar:

call: referidos a llamadas en las que se envía una petición y se espera por una respuesta del servidor. Siendo realizadas desde otros procesos de Erlang.
cast: estas son llamadas que se envían y no se espera por una respuesta. También son realizadas [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/cables-150x150.jpg" alt="" title="cables" width="150" height="150" class="alignleft size-thumbnail wp-image-1276" /> Una de las grandes potencias de Erlang es su capacidad para construir servidores. A través de OTP, esta tarea se convierte en algo tan sencillo, que asombra ver con qué pocas líneas de código se crea un servidor.</p>
<p>En este caso vamos a montar un servidor UDP. Esto lo revisé en su día porque estuve realizando un pequeño servidor para el protocolo <em>syslog</em>, de lo que resultó este servidor, que permite pasar a través de un manejador de eventos (gen_event) los mensajes de syslog recibidos a través del puerto 514 en formato UDP.</p>
<p>En principio, comentaré un poco la estructura del comportamiento (<em>behaviour</em>) de Erlang/OTP que emplearemos: <em>gen_server</em>.</p>
<h3>Empleando los <em>gen_server</em></h3>
<p>El <em>gen_server</em> es el comportamiento más básico que se encuentra disponible en OTP, ya que sobre él se construyen otros como <em>gen_fsm</em>. Este comportamiento específico se fundamenta en la recepción de mensajes y su manejo a través de unos callbacks, de modo que tenemos tres tipos de mensajes que podemos procesar:</p>
<ul>
<li><strong>call</strong>: referidos a llamadas en las que se envía una petición y se espera por una respuesta del servidor. Siendo realizadas desde otros procesos de Erlang.</li>
<li><strong>cast</strong>: estas son llamadas que se envían y no se espera por una respuesta. También son realizadas desde otros procesos de Erlang.</li>
<li><strong>info</strong>: este podría considerarse un comodín, ya que en esta categoría entran todos los mensajes que no entran en las anteriores. Normalmente, aquí es donde recibiremos la información UDP y TCP de los servidores que creemos de cara a la red.</li>
</ul>
<p>La estructura de un código con <tt>gen_server</tt> es la siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>server<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">author</span><span style="color: #109ab8;">&#40;</span><span style="">'bombadil@bosqueviejo.net'</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">behaviour</span><span style="color: #109ab8;">&#40;</span>gen_server<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">SERVER</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">MODULE</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>start_link<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>init<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> handle_call<span style="color: #014ea4;">/</span><span style="color: #ff9600;">3</span><span style="color: #6bb810;">,</span> handle_cast<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> handle_info<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span>
         terminate<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> code_change<span style="color: #014ea4;">/</span><span style="color: #ff9600;">3</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">record</span><span style="color: #109ab8;">&#40;</span><span style="color: #d400ed;">state</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
start_<span style="color: #fa6fff;">link</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">gen_server</span>:<span style="color: #006600;">start_</span><span style="color: #fa6fff;">link</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span>local<span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">SERVER</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">MODULE</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">init</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> #<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">handle_call</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Request</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_From</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Reply</span> <span style="color: #014ea4;">=</span> ok<span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>reply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Reply</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">handle_cast</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Msg</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">handle_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Info</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">terminate</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Reason</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #006600;">ok</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">code_change</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_OldVsn</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Extra</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Si guardamos esta estructura como <tt>server.erl</tt> (que es el nombre del módulo, tal y como se indica en la primera línea), el sistema compilará y lo podremos incluso lanzar con el comando:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">server:<span style="color: #006600;">start_</span><span style="color: #fa6fff;">link</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<h3>Convirtiendo nuestro <em>gen_server</em> en servidor UDP</h3>
<p>Para convertir nuestro <tt>gen_server</tt> en un servidor UDP solo necesitamos abrir en escucha el puerto que queramos en modo UDP a través de <tt>gen_udp</tt> y el resto lo hará la estructura <tt>gen_server</tt>. Sería tan simple como modificar la función <tt>init</tt> para que albergase el siguiente código:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">init</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Port</span> <span style="color: #014ea4;">=</span> <span style="color: #ff9600;">5000</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">gen_udp</span>:<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">error_logger</span>:<span style="color: #ff3c00;">info_msg</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;Listen in port ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> #<span style="color: #d400ed;">state</span><span style="color: #109ab8;">&#123;</span>socket<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Y también la estructura del registro de estado, para albergar la información que necesitamos almacenar en el proceso, que será el recurso del puerto abierto:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">record</span><span style="color: #109ab8;">&#40;</span><span style="color: #d400ed;">state</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>socket<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Es bueno que, además, agregemos en el <tt>terminate</tt> la cláusula que nos permita cerrar el servidor UDP, esto lo podemos agregar modificando la función <tt>termiante</tt> de la siguiente forma:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">terminate</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Reason</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">gen_udp</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">State</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">state</span><span style="color: #6bb810;">.</span>socket<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    ok<span style="color: #6bb810;">.</span></pre></div></div>

<p>Por último, vamos a hacer que cada mensaje que nos llegue desde el servidor UDP se presente a modo de log en la consola. Esto lo haremos modificando la función <tt>handle_info</tt>, que como habíamos visto antes, es la que recibe los mensajes UDP:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">handle_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Info</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">error_logger</span>:<span style="color: #ff3c00;">info_msg</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;Received via INFO: ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Info</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>noreply<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">State</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<h3>Probando el servidor</h3>
<p>Para probarlo, solo tenemos que ejecutar en una consola:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ erl 
Erlang R15B (erts-5.9) [source] [64-bit] [smp:4:4] [async-threads:0] [kernel-poll:false]
&nbsp;
Eshell V5.9  (abort with ^G)
1&gt; server:start_link().
&nbsp;
=INFO REPORT==== 21-Mar-2012::10:52:44 ===
Listen in port 5000
{ok,&lt;0.34.0&gt;}</pre></div></div>

<p>Abrimos otra consola, y ejecutamos el siguiente comando para generar un paquete UDP:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ nc -u localhost 5000
hola</pre></div></div>

<p><strong>NOTA</strong>: tras escribir <tt>hola</tt> hay que presionar el retorno de carro (enter o intro) para que el paquete sea enviado.</p>
<p>Esto generará en la consola de Erlang el siguiente mensaje:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">=INFO REPORT==== 21-Mar-2012::10:54:01 ===
Received via INFO: {udp,#Port&lt;0.506&gt;,{127,0,0,1},36772,&quot;hola\n&quot;}</pre></div></div>

<p>Empleando el <em>match</em> en la función <tt>handle_info</tt> e incluso con expresiones regulares o lo que queramos, podremos tratar de forma más adecuada el mensaje.</p>
<p>Un ejemplo de aplicación de este servidor, como comenté al principio, se puede ver en este proyecto que comencé hace tiempo, <a href="http://project.bosqueviejo.net/esyslog">un servidor de <em>syslog</em></a>, que se basa en la recepción de mensajes por el puerto UDP 514, y el envío, a través de <tt>gen_event</tt> de los mensajes recibidos.</p>
<h3>Conclusiones</h3>
<p>Con este ejemplo, Erlang demuestra que es muy fácil construir servidores de red, con muy pocas líneas de código. En este ejemplo, el hecho de ser un servidor UDP permite eliminar el payload de la escucha, aceptación y mantenimiento de conexión con el destinatario, simplemente se acepta el mensaje, se lee y procesa, muy simple y con un buen rendimiento del sistema.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/03/21/erlang-servidores-udp/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>¿Qué es el código Ravioli?</title>
		<link>http://bosqueviejo.net/2012/03/05/ravioli-codigo/</link>
		<comments>http://bosqueviejo.net/2012/03/05/ravioli-codigo/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 18:16:17 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[antipatrones]]></category>
		<category><![CDATA[código ravioli]]></category>
		<category><![CDATA[código spaghetti]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1249</guid>
		<description><![CDATA[ Leyendo un documento sobre Erlang, en el que introduce el concepto de módulos parametrizados, encuentro un aviso que dice (traducido): cuidado con el código Ravioli. Por lo que llego a preguntarme&#8230; ¿qué es el código Ravioli?
Hasta ahora, yo conocía el código Spaguetti, que se basaba en la programación con saltos entre las líneas del código, vamos, el uso de la sentencia goto, que quedó obsoleta con la programación estructurada. Pero al adentrarnos en la programación estructurada, surge otro anti-patrón a tener en cuenta, que es el código Ravioli.
El código Ravioli se basa en que el código se refactoriza en demasiados trozos pequeños del mismo que llegan a ser difíciles o imposibles de seguir. Este caso se da también en la programación orientada a objetos, donde el origen del código ya no está disperso entre funciones o procedimientos, sino también entre clases y paquetes, haciendo que el código sea difícilmente trazable.
Los consejos que podemos seguir para no caer en este tipo de programación son:

No ir más allá de 7 +/- 2 trozos de código. Si el código que estamos trazando (propio nuestro) tiene que ahondar en más de 7 (o 9 métodos/funciones/&#8230;) entonces quizás comience a caer en la definición [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/ravioli.jpeg" alt="" title="ravioli" width="150" height="150" class="alignleft size-full wp-image-1250" /> Leyendo un <a href="http://www.erlang.se/workshop/2003/paper/p29-carlsson.pdf">documento sobre Erlang</a>, en el que introduce el concepto de módulos parametrizados, encuentro un aviso que dice (traducido): <em>cuidado con el código Ravioli</em>. Por lo que llego a preguntarme&#8230; ¿qué es el código Ravioli?<span id="more-1249"></span></p>
<p>Hasta ahora, yo conocía el código Spaguetti, que se basaba en la programación con saltos entre las líneas del código, vamos, el uso de la sentencia <em>goto</em>, que quedó obsoleta con la programación estructurada. Pero al adentrarnos en la programación estructurada, surge otro anti-patrón a tener en cuenta, que es el <a href="http://c2.com/cgi/wiki?RavioliCode">código Ravioli</a>.</p>
<p>El código Ravioli se basa en que el código se refactoriza en demasiados trozos pequeños del mismo que llegan a ser difíciles o imposibles de seguir. Este caso se da también en la programación orientada a objetos, donde el origen del código ya no está disperso entre funciones o procedimientos, sino también entre clases y paquetes, haciendo que el código sea difícilmente trazable.</p>
<p>Los consejos que podemos seguir para no caer en este tipo de programación son:</p>
<ul>
<li><strong>No ir más allá de 7 +/- 2 trozos de código</strong>. Si el código que estamos trazando (propio nuestro) tiene que ahondar en más de 7 (o 9 métodos/funciones/&#8230;) entonces quizás comience a caer en la definición de Ravioli.</li>
<li><strong>Programación por parejas</strong>: si uno de los dos se comienza a perder, es mala señal.</li>
<li><strong>Refactorización Sin Piedad</strong>: refactorizar intentando hacer común lo específico de modo que si hay dos funciones que hagan cosas similares, se unifiquen, y si hay dos objetos también similares, igual.</li>
</ul>
<p>&#8230;y sobre todo, mucho sentido común. Intenta escribir cosas lógicas, que llegando a un momento dado, olvidando que lo has escrito tú, al verlo, consideres que esa es la ubicación lógica donde lo encontraría cualquier persona que viese de nuevas el código.</p>
<p>Con todo eso, el código Ravioli no será más un problema para tus códigos <img src='http://bosqueviejo.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/03/05/ravioli-codigo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>V8: Extendiendo PHP</title>
		<link>http://bosqueviejo.net/2012/02/28/v8-extendiendo-php/</link>
		<comments>http://bosqueviejo.net/2012/02/28/v8-extendiendo-php/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 17:39:16 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[v8]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1243</guid>
		<description><![CDATA[ Hace prácticamente un año escribí un artículo denominado Spidermonkey: extendiendo PHP, donde comentaba como emplear Spidermonkey para poder emplearlo como lenguaje de extensión a un núcleo sencillo hecho en PHP.
Incluso lo emplee como elemento principal en el desarrollo de PHAS-JS, realizando un servidor de aplicaciones en PHP, con la potencia que brindan muchas de sus librerías, pero escribiendo código de forma segura en JavaScript (o ECMAScript).
Hoy voy a tratar otra máquina que permite ejecutar código JavaScript dentro de PHP, de la misma forma que cuando vimos Spidermonkey, pero variando la forma en la que interactúa con PHP. En esta ocasión tenemos entre nosotros la máquina: el V8 de Google. Va a estar un poco inspirado en lo que he ido comentando con Sergio, que he visto que ha escrito también al respecto en su blog: PHP y JavaScript se entienden.
Instalando
Lo primero, es que si tenemos como paquete el libv8-dev, todo será más fácil ya que se resume en estos sencillos pasos (esto es válido para Debian y Ubuntu):

apt-get install libv8-dev
pecl install v8js

Esta es una de las implementaciones de V8 que hay para PHP, también está disponible V8 (a secas) que es un módulo que intenta imitar la implementación de [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/V8-150x150.png" alt="" title="V8" width="150" height="150" class="alignleft size-thumbnail wp-image-1244" /> Hace prácticamente un año escribí un artículo denominado <a href="/2011/02/24/spidermonkey-extendiendo-php/">Spidermonkey: extendiendo PHP</a>, donde comentaba como emplear Spidermonkey para poder emplearlo como lenguaje de extensión a un núcleo sencillo hecho en PHP.</p>
<p>Incluso lo emplee como elemento principal en el desarrollo de <a href="http://phas-js.org">PHAS-JS</a>, realizando un servidor de aplicaciones en PHP, con la potencia que brindan muchas de sus librerías, pero escribiendo código de forma segura en JavaScript (o ECMAScript).</p>
<p>Hoy voy a tratar otra máquina que permite ejecutar código JavaScript dentro de PHP, de la misma forma que cuando vimos Spidermonkey, pero variando la forma en la que interactúa con PHP. En esta ocasión tenemos entre nosotros la máquina: el V8 de Google. Va a estar un poco inspirado en lo que he ido comentando con Sergio, que he visto que ha escrito también al respecto en su blog: <a href="https://sergio.am/leer/php-y-javascript-se-entienden">PHP y JavaScript se entienden</a>.</p>
<h3>Instalando</h3>
<p>Lo primero, es que si tenemos como paquete el <em>libv8-dev</em>, todo será más fácil ya que se resume en estos sencillos pasos (esto es válido para Debian y Ubuntu):</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">apt-get install libv8-dev
pecl install v8js</pre></div></div>

<p>Esta es una de las implementaciones de V8 que hay para PHP, también está disponible V8 (a secas) que es un módulo que intenta imitar la implementación de Spidermonkey, con lo que, si tienes un código que emplee el sistema de spidermonkey, pasar a v8 debe de ser cambiar muy poquitas cosas. <em>No obstante este código está marcado como <strong>experimental</strong> y hay cosas que no funcionan del todo</em>. La instanación sería:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">apt-get install libv8-dev
git clone https://github.com/metagoto/v8.git
cd v8 &amp;&amp; phpize &amp;&amp; ./configure &amp;&amp; make &amp;&amp; make install</pre></div></div>

<p>La configuración es compatible si instalamos los dos, ya que es:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">extension=v8js.so
extension=v8.so</pre></div></div>

<p><strong>Actualización</strong>: escribí un email a <em>metagoto</em> sobre el mantenimiento y mejora del módulo v8 para PHP. La respuesta fue que esa implementación la realizó para poder jugar y ver cómo se comportaba el sistema v8, y que no le pudo dedicar mucho tiempo, es más, abandonó el desarrollo y no tiene pensado retomarlo. Sobre el problema que observé del paso de objetos y que no pasaba sus métodos, parece que el problema no es trivial, por lo que, desecho la idea de tomarlo como una solución práctica y la dejo únicamente para pruebas y ensayos.</p>
<h3>Probando&#8230;</h3>
<p>En principio, podemos repetir la misma prueba que hicimos en el artículo de spidermonkey, a modo de poder enseñarlo de ambas formas. El código, por tanto sería así:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// crea la máquina para JavaScript</span>
<span style="color: #000088;">$js</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> V8Js<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// define valores para el entorno JS</span>
<span style="color: #000088;">$js</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">a</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$js</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">b</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// define el código a ejecutar</span>
<span style="color: #000088;">$script</span> <span style="color: #339933;">=</span> <span style="color: #0000cc; font-style: italic;">&lt;&lt;&lt;END
  c = PHP.a + PHP.b;
END</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// evalua el script y muestra el resultado</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;La suma de <span style="color: #006699; font-weight: bold;">$a</span> y <span style="color: #006699; font-weight: bold;">$b</span> es: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$js</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">executeScript</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$script</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>La pega que tiene este, en comparación con spidermonkey, es que las funciones solo se pueden pasar si son anónimas (como variables) y que la ejecución restringe o separa lo que se pasa desde PHP en un objeto específico, por lo que queda un poco engorroso (desde mi punto de vista).</p>
<p>Con el tema de los objetos pasa igual, se pueden pasar objetos, pero no clases, con lo que no se pueden realizar instancias nuevas, a menos que se emplee una función anónima que haga las veces de factory o singleton.</p>
<p>El código de <em>v8</em>, que intenta emular a <em>spidermonkey</em> facilita esto agregando registro de funciones, clases y variables en la parte global. No obstante, este código no es completamente funcional, ya que, en las pruebas realizadas, por ejemplo, no se tiene acceso a los métodos de las clases registradas cuando se crea un nuevo objeto dentro de V8.</p>
<h3>Conclusiones</h3>
<p>La máquina V8 ha demostrado ser un gran intérprete de JavaScript, ya que es la que emplea Google en el navegador Chorme, no obstante, su integración con PHP falta que madure un poco y se ajuste en usabilidad a algo similar a lo que se puede conseguir con Spidermonkey.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/02/28/v8-extendiendo-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Montículos</title>
		<link>http://bosqueviejo.net/2012/02/12/monticulos/</link>
		<comments>http://bosqueviejo.net/2012/02/12/monticulos/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 13:56:48 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[heapsort]]></category>
		<category><![CDATA[montículos]]></category>
		<category><![CDATA[priorityqueue]]></category>
		<category><![CDATA[robert w floyd]]></category>
		<category><![CDATA[uned]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1223</guid>
		<description><![CDATA[ Pues sí, otra vez de exámenes, otra vez estudiando, y llego a un apartado, en el que lo que decía el libro me sorprende y, al implementarlo, me confirmo. La teoría o lo que viene en los libros no es 100% fiable, en caso de teorías matemáticas, físicas, &#8230; o de computación, hay que comprobar lo que nos indican los libros, porque podemos encontrarnos con una errata.
Teniendo en cuenta que lo que indica el libro es un pseudocódigo, es peor aún, puesto que quien lo escribe está seguro de hacerlo bien, y no dudo que incluso lo haya comprobado, pero claro, nos encontramos con que, como no es un lenguaje concreto, pueda ser una interpretación de una implementación, para la cual, se ha podido perder algo de sustancia por el camino, o cometer un error tipográfico.
Pero al grano. Montículos.
¿Qué es un montículo?
Un montículo es un árbol binario balanceado que cumple con la premisa de que: ningún padre tiene un hijo mayor (montículo de máximos) o menor (montículo de mínimos) a él. Una definición corta y concreta, ¿no?
Esta estructura de datos fue propuesta por Robert W. Floyd (premio Turing en 1978) para resolver el problema de la ordenación de elementos [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/floyd-150x150.png" alt="" title="floyd" width="150" height="150" class="alignleft size-thumbnail wp-image-1224" /> Pues sí, otra vez de exámenes, otra vez estudiando, y llego a un apartado, en el que lo que decía el libro me sorprende y, al implementarlo, me confirmo. La teoría o lo que viene en los libros no es 100% fiable, en caso de teorías matemáticas, físicas, &#8230; o de computación, hay que comprobar lo que nos indican los libros, porque podemos encontrarnos con una errata.</p>
<p>Teniendo en cuenta que lo que indica el libro es un pseudocódigo, es peor aún, puesto que quien lo escribe está seguro de hacerlo bien, y no dudo que incluso lo haya comprobado, pero claro, nos encontramos con que, como no es un lenguaje concreto, pueda ser una interpretación de una implementación, para la cual, se ha podido perder algo de sustancia por el camino, o cometer un error tipográfico.</p>
<p>Pero al grano. Montículos.</p>
<h3>¿Qué es un montículo?</h3>
<p>Un montículo es un árbol binario balanceado que cumple con la premisa de que: <em>ningún padre tiene un hijo mayor (montículo de máximos) o menor (montículo de mínimos) a él</em>. Una definición corta y concreta, ¿no?</p>
<p>Esta estructura de datos fue propuesta por <a href="http://es.wikipedia.org/wiki/Robert_Floyd">Robert W. Floyd</a> (premio Turing en 1978) para resolver el problema de la ordenación de elementos dentro de un vector, el famoso <a href="http://es.wikipedia.org/wiki/Heapsort"><em>heapsort</em></a> (u ordenación por montículo).</p>
<p>En la asignatura de <em>Programación y Estructuras de Datos Avanzadas</em> (en la carrera de Grado en Ingenería Informática de la UNED), se propone al inicio de la asignatura, como conocimiento de las estructuras de datos, el montículo.</p>
<p><a href="http://bosqueviejo.net/wp-content/uploads/monticulo.png"><img src="http://bosqueviejo.net/wp-content/uploads/monticulo-300x274.png" alt="" title="monticulo" width="300" height="274" class="aligncenter size-medium wp-image-1226" /></a></p>
<p>El montículo, aunque conceptualmente se dibuja en forma de árbol, está implementado sobre un vector. Ya que es balanceado y binario, un nodo solo puede contener dos hijos. La formula para acceder a cada hijo, dado el índice del padre (i), sería:</p>
<pre>
hijo_izquierdo = 2i
hijo_derecho = 2i+1
</pre>
<p>El acceso al padre se realizaría con una división entera: <tt>i / 2</tt>.</p>
<h3>¿Para qué sirve un montículo?</h3>
<p>El montículo se emplea en lenguajes de alto y medio nivel, muchas veces sin darnos cuenta. En Java, por ejemplo, se implementa a través de la clase <a href="http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html">PriorityQueue</a>, la cual permite, a través de un comparador, implementar la ordenación interna del montículo. En otros lenguajes puede aparecer igualmente como cola de prioridad (PriorityQueue) o como montículo (Heap).</p>
<p>El montículo en sí permite:</p>
<ul>
<li>Ordenar elementos de un vector de forma fácil y óptima, pudiendo implementar un comparador a medida.</li>
<li>Búsquedas el máximos, mínimos, o cualquier otro factor a tener en cuenta en la selección de búsqueda de elementos.</li>
<li>En problemas específicos de grafos como el recubrimiento mínimo de Prim o el camino más corto de Dijkstra.</li>
</ul>
<h3>Implementación del algoritmo</h3>
<p>Me ha costado un poco decidir el lenguaje en el que implementarlo, finalmente, he optado por Ruby, ya que su código queda bastante pseudocodificado, pero igualmente habría quedado igual de bien en Python. El código sería:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MonticuloMaximos
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Vale, esto es lo básico, la definición de la clase. Ahora vamos a ir creando los métodos:</p>
<ul>
<li><strong>inicializador</strong> (o constructor): inicializa el vector interno, de modo que en el momento de crear el montículo, este estará vacío:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@vector</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>vacio?</strong>: esta es una de las cosas que más me gusta de Ruby, que puedes poner en un método el símbolo de interrogación, con lo que queda bastante pseudocodificado lo que hace el método en sí. Pregunta si el montículo está vacío, y la respuesta será lógica: sí o no (veradero o falso):

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> vacio?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#006600; font-weight:bold;">&#40;</span>@vector.<span style="color:#9900CC;">length</span> == <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>flotar</strong>: aquí ya comenzamos con las acciones básicas de un montículo. La acción de <em>flotar</em>, se emplea cuando se agrega un elemento nuevo a la estructura. Lo más simple, dado que el montículo se implementa en un vector, es agregar al final del vector el elemento y <em>flotarlo</em>, hasta que su peso nos diga que está en el lugar indóneo, esto hace que el coste del algoritmo sea lineal, y por lo cual, óptimo:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> flotar<span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
        padre = i <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">2</span>
        <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&gt;</span><span style="color:#006666;">1</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>padre<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&lt;</span>@vector<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>padre<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>padre<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
            i = i <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">2</span>
            padre = i <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">2</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>hundir</strong>: sería la contrapartida a flotar. En este caso, lo que se hace es que, si eliminamos la <em>cima del montículo</em>, la acción rápida, sería mover el último elemento del vector al principio, cambiar el dimensionamiento del vector y realizar este algoritmo para llevar (o hundir) al elemento a su posición correcta. Igualmente, el algoritmo es lineal:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> hundir<span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">begin</span>
            hi = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> i
            hd = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>
            <span style="color:#CC0066; font-weight:bold;">p</span> = i
            <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>hd <span style="color:#006600; font-weight:bold;">&lt;</span>= <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">length</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>hd<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
                i = hd
            <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>hi <span style="color:#006600; font-weight:bold;">&lt;</span>= <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">length</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>hi<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
                i = hi
            <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">p</span> != i<span style="color:#006600; font-weight:bold;">&#41;</span>
                <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>p<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>p<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#9966CC; font-weight:bold;">until</span> <span style="color:#CC0066; font-weight:bold;">p</span> == i
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>insertar</strong>: en este método, insertamos (como bien dijimos en flotar) un elemento en la estructura, por lo que, hacemos eso mismo, agregamos el elemento y lo flotamos:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> insertar<span style="color:#006600; font-weight:bold;">&#40;</span> e <span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span>e<span style="color:#006600; font-weight:bold;">&#41;</span>
        flotar<span style="color:#006600; font-weight:bold;">&#40;</span>@vector.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>primero</strong>: nos da el primer elemento del montículo (la <em>cima</em>), pero sin eliminarlo de la estructura. Por lo que el algoritmo es:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> primero<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>cima</strong>: igual que el anterior, pero eliminando el elemento de la cima. Para ello, como se comentó en <em>hundir</em>, se toma el último elemento, se inserta en la cima (que queda vacía) y se <em>hunde</em> hacia su posición correcta. El algoritmo sería:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> cima<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        e = <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">1</span>
            <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">pop</span>
            hundir<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">else</span>
            <span style="color:#0066ff; font-weight:bold;">@vector</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
        e
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li>Como ayuda o soporte vamos a crear dos métodos más, uno genérico a Ruby (y presente en otros lenguajes como Java, PHP y Python, pero con distinto nombre) que permite tener una representación en formato texto (o cadena, o <em>string</em>) del montículo: <strong>to_s</strong>; y otro método que nos dará los elementos del montículo en un vector ordenado (eliminándolos del montículo, claro): <strong>ordenado</strong>; la implementación de ambos:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> to_s<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#996600;">&quot;[ &quot;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;, &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot; ]&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> ordenado<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        a = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        a.<span style="color:#9900CC;">push</span> cima <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#9966CC; font-weight:bold;">not</span> vacio?
        a
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
</ul>
<p>Una vez visto todo el código, podemos hacer una prueba como la siguiente, en la que insertaremos unos datos aleatorios y obtendremos el resultado de su almacenamiento en forma de montículo, y el resultado en un vector ordenado:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">a = <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#006666;">6</span>, <span style="color:#006666;">4</span>, <span style="color:#006666;">3</span>, <span style="color:#006666;">1</span>, <span style="color:#006666;">5</span>, <span style="color:#006666;">2</span>, <span style="color:#006666;">4</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
m = MonticuloMaximos.<span style="color:#9900CC;">new</span>
a.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>e<span style="color:#006600; font-weight:bold;">|</span>
    m.<span style="color:#9900CC;">insertar</span><span style="color:#006600; font-weight:bold;">&#40;</span>e<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> m
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;[ &quot;</span> <span style="color:#006600; font-weight:bold;">+</span> m.<span style="color:#9900CC;">ordenado</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;, &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot; ]&quot;</span></pre></div></div>

<p>El resultado es el siguiente:</p>
<pre>
[ 6, 5, 4, 1, 4, 2, 3 ]
[ 6, 5, 4, 4, 3, 2, 1 ]
</pre>
<p><strong>NOTA</strong>: Como se podrá ver en la implementación, este código estaba preparado para vectores que enumerasen sus elementos en base a 1..N, y sin embargo, todos los lenguajes (a excepción de Pascal, Modula-2, y otros similares) numeran los vectores de 0..N-1, por lo que en cada acceso al atributo <tt>@vector</tt> se ha tenido que decrementar en 1 el número, para pasar de la notación 1..N a 0..N-1.</p>
<h3>Conclusiones</h3>
<p>El montículo es un gran elemento que se sigue empleando por su simpleza y óptima respuesta, ya que en lugar de emplear estructura de árbol, grafos o listas, emplea un simple vector, por lo que cada acción a realizar sobre él resulta con un coste bastante reducido. Así mismo, como había dicho al principio, esté presente en todos los lenguajes, ya sea con el nombre de <em>heap</em>, o <em>PriorityQueue</em>, con la capacidad de poder implementar su comparador (para máximos, mínimos o a medida), por lo que no hay excusa para no emplearlo cuando la situación lo requiera.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/02/12/monticulos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Las gemas de Ruby</title>
		<link>http://bosqueviejo.net/2012/01/02/las-gemas-de-ruby/</link>
		<comments>http://bosqueviejo.net/2012/01/02/las-gemas-de-ruby/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 17:03:31 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1165</guid>
		<description><![CDATA[ Tengo a Ruby un poco abandonado, por lo que me he decidido a escribir un poco acerca de él, al igual que hice con Python, para detallar un poco cómo son los paquetes de código (o librerías) de Ruby: las gemas.
Las gemas de Ruby son paquetes de librerías para Ruby que se instalan en el sistema y quedan listas para ser usadas, con un simple require o con mecanismos que aporta el propio sistema de gemas para Ruby.
El gestor de gemas: rubygems
En distribuciones de GNU/Linux, e instalaciones automáticas para Windows, se nos habilita un comando, generalmente, que nos permite agregar librerías y código de un repositorio muy extenso de código listo para usar. Esto es conocido como el gestor de gemas, rubygems, o simplemente gem.
El gestor de gemas es un comando que nos permite listar las gemas instaladas, buscar gemas remotas o localmente (de las instaladas), instalar, actualizar y eliminar gemas. Se puede saber si está instalado simplemente ejecutando:

gem --version

La última versión a día de hoy es la 1.8.12, actualizar el sistema de gemas es tan simple como ejecutar:

gem update --system

Instalar una gema
Por ejemplo, si queremos usar el código siguiente:

require &#34;rubygems&#34;;
require &#34;json&#34;;
&#160;
puts &#91; &#34;hola a todos&#34;, 12, &#34;C/Sin nombre, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/rubygems-150x150.jpg" alt="" title="rubygems" width="150" height="150" class="alignleft size-thumbnail wp-image-1166" /> Tengo a Ruby un poco abandonado, por lo que me he decidido a escribir un poco acerca de él, al igual que hice con Python, para detallar un poco cómo son los paquetes de código (o librerías) de Ruby: las gemas.<span id="more-1165"></span></p>
<p>Las gemas de Ruby son paquetes de librerías para Ruby que se instalan en el sistema y quedan listas para ser usadas, con un simple <em>require</em> o con mecanismos que aporta el propio sistema de gemas para Ruby.</p>
<h3>El gestor de gemas: rubygems</h3>
<p>En distribuciones de GNU/Linux, e instalaciones automáticas para Windows, se nos habilita un comando, generalmente, que nos permite agregar librerías y código de un repositorio muy extenso de código listo para usar. Esto es conocido como el gestor de gemas, <em>rubygems</em>, o simplemente <em>gem</em>.</p>
<p>El gestor de gemas es un comando que nos permite listar las gemas instaladas, buscar gemas remotas o localmente (de las instaladas), instalar, actualizar y eliminar gemas. Se puede saber si está instalado simplemente ejecutando:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gem --version</pre></div></div>

<p>La última versión a día de hoy es la 1.8.12, actualizar el sistema de gemas es tan simple como ejecutar:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gem update --system</pre></div></div>

<h3>Instalar una gema</h3>
<p>Por ejemplo, si queremos usar el código siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;rubygems&quot;</span>;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;json&quot;</span>;
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;">&quot;hola a todos&quot;</span>, <span style="color:#006666;">12</span>, <span style="color:#996600;">&quot;C/Sin nombre, 25&quot;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_json</span></pre></div></div>

<p>Tendremos que instalar previamente la gema <em>json</em>. Para instalarla, solo tenemos que ejecutar el siguiente comando:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo gem install json
[sudo] password for marubio: 
Building native extensions.  This could take a while...
Successfully installed json-1.6.4
1 gem installed
Installing ri documentation for json-1.6.4...
Installing RDoc documentation for json-1.6.4...</pre></div></div>

<p>Como se puede apreciar, se instala la gema y se genera la documentación para <em>ri</em> y <em>rdoc</em>. La generación de la documentación es bastante lenta y si tenemos que instalar muchas gemas, puede ser algo tedioso. Se puede eliminar esta tarea agregando al comando de instalación: <tt>--no-ri --no-rdoc</tt></p>
<p>Ahora, cuando listemos los paquetes instalados podremos ver:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo gem list
&nbsp;
*** LOCAL GEMS ***
&nbsp;
json (1.6.4)</pre></div></div>

<p>Nos indica la versión, ya que podríamos tener varias versiones instaladas y conviviendo, y desde el código emplear la que requiramos específicamente. Si queremos instalar una versión específica de un paquete, podemos hacerlo agregando la opción, por ejemplo: <tt>--v=1.6.1</tt></p>
<h3>Buscando una gema</h3>
<p>Si queremos buscar una gema específica del directorio de gemas, podemos hacerlo a través de la propia página web: <a href="http://rubygems.org">RubyGems</a>; o a través del comando:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ gem search -r jsonn
&nbsp;
*** REMOTE GEMS ***
&nbsp;
active_record_serialize_json (0.1.2)
activejson (0.1.2)
activeresource_json_patch (0.0.1)
assert_json (0.1.1)
capcode-render-json (0.2.0)
capybara-json (0.1.1)
colorful_json (0.9.1)
csv2json (0.2.0)
cucumber-json (0.0.2)
dm-json-search (0.0.3)
[...]</pre></div></div>

<p>La base de datos de gemas tiene la friolera de más de 32 mil gemas, por lo que, no es de extrañar que ante algo trivial (como JSON) puedan aparecer cientos de gemas. A la hora de buscar deberemos de ser más precisos con los términos a elegir.</p>
<h3>Conclusiones</h3>
<p>Ha sido una introducción muy ligera a este entorno de gestión de paquetes de Ruby, lo sé, pero al menos complementa un poco la entrada de hace algunos meses sobre <a href="/2011/03/07/bundler-despliega-facilmente-rails/">Bundler</a> y da un poco de información sobre los comandos más usuales a la hora de instalar una librería en Ruby, ya sea para código scripting o para Rails.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/01/02/las-gemas-de-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Catalyst: framework web para Perl</title>
		<link>http://bosqueviejo.net/2011/11/29/catalyst-framework-web-para-perl/</link>
		<comments>http://bosqueviejo.net/2011/11/29/catalyst-framework-web-para-perl/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 18:20:22 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[catalyst]]></category>
		<category><![CDATA[desarrollo web]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=777</guid>
		<description><![CDATA[ Justo cuando colgaba la encuesta sobre: Si tuvieses que hacer un sitio web dinámico, ¿en qué tecnología lo harías?; busqué un framework en los lenguajes más populares de desarrollo web y, topé con Catalyst, un framework en Perl para el desarrollo de aplicaciones web.
Después de un recorrido por Symfony (PHP), Rails (Ruby) y Django (Python), he decidido echarle un vistazo a Catalyst (Perl) para ver qué novedades integra y en qué mejora, tanto a nivel de rendimiento, como a nivel de desarrollo, la generación de sitios web dinámicos.
Perspectiva MVC
Cada entorno integra MVC de una forma diferente, incluso lo que se entiende por MVC, desde los primeros libros a finales de los 70 y principios de los 80, es un esquema en el que la Vista puede interactuar con el modelo, al igual que el controlador con la vista y con el modelo.
En Rails, se presenta el fat model, donde la codificación referente a base de datos se realiza en estos, y el flujo de la aplicación recae en los controladores, que deciden qué tipo de vista o presentación de la información emplear, dando facilidades para la presentación en HTML, JSON, XML&#8230; e incluso vía email.
En cambio, Django, no dispone [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/perl_catalyst.png" alt="" title="perl_catalyst" width="105" height="105" class="alignleft size-full wp-image-1093" /> Justo cuando colgaba la encuesta sobre: <em>Si tuvieses que hacer un sitio web dinámico, ¿en qué tecnología lo harías?</em>; busqué un framework en los lenguajes más populares de desarrollo web y, topé con <a href="http://www.catalystframework.org/">Catalyst</a>, un framework en Perl para el desarrollo de aplicaciones web.<span id="more-777"></span></p>
<p>Después de un recorrido por Symfony (PHP), Rails (Ruby) y Django (Python), he decidido echarle un vistazo a Catalyst (Perl) para ver qué novedades integra y en qué mejora, tanto a nivel de rendimiento, como a nivel de desarrollo, la generación de sitios web dinámicos.</p>
<h3>Perspectiva MVC</h3>
<p>Cada entorno integra MVC de una forma diferente, incluso lo que se entiende por MVC, desde los primeros libros a finales de los 70 y principios de los 80, es un esquema en el que la Vista puede interactuar con el modelo, al igual que el controlador con la vista y con el modelo.</p>
<p>En Rails, se presenta el <em>fat model</em>, donde la codificación referente a base de datos se realiza en estos, y el flujo de la aplicación recae en los controladores, que deciden qué tipo de vista o presentación de la información emplear, dando facilidades para la presentación en HTML, JSON, XML&#8230; e incluso vía email.</p>
<p>En cambio, Django, no dispone de controlador como tal, ya que lo nombran por defecto como <em>views</em>, siendo esta la entidad que controla el flujo y la presentación, ayudada de la plantillas usando DTL. En este caso, la parte de MVC queda más difusa y ellos mismos explican en su web, que se podría decir más bien que Django es MTV (Model-Template-View).</p>
<p>Catalyst, sin embargo, tiene más semejanza a Rails en este sentido. Tiene un parte para los controladores, una parte para los modelos y otra parte para las vistas. Así mismo, las vistas se desarrollan, al igual que Django y Rails, con un sistema de plantillas (templates).</p>
<p>Al crear un proyecto, tan solo ejecutando el siguiente comando, se genera la estructura de ficheros que podemos ver a continuación:</p>
<pre>
$ catalyst.pl miproject
created "miproject"
created "miproject/script"
created "miproject/lib"
created "miproject/root"
created "miproject/root/static"
created "miproject/root/static/images"
[...]
$ tree
.
├── Changes
├── lib
│   ├── miproject
│   │   ├── Controller
│   │   │   └── Root.pm
│   │   ├── Model
│   │   └── View
│   └── miproject.pm
├── Makefile.PL
├── miproject.conf
├── miproject.psgi
├── README
├── root
│   ├── favicon.ico
│   └── static
│       └── images
│           ├── btn_120x50_built.png
│           ├── btn_120x50_built_shadow.png
│           ├── btn_120x50_powered.png
│           ├── btn_120x50_powered_shadow.png
│           ├── btn_88x31_built.png
│           ├── btn_88x31_built_shadow.png
│           ├── btn_88x31_powered.png
│           ├── btn_88x31_powered_shadow.png
│           └── catalyst_logo.png
├── script
│   ├── miproject_cgi.pl
│   ├── miproject_create.pl
│   ├── miproject_fastcgi.pl
│   ├── miproject_server.pl
│   └── miproject_test.pl
└── t
    ├── 01app.t
    ├── 02pod.t
    └── 03podcoverage.t

10 directories, 25 files
</pre>
<p>En el directorio <strong>lib/miproject</strong> es donde está el código principal.</p>
<h3>Los controladores</h3>
<p>A diferencia de otros entornos, las URLs o rutas para acceso a los métodos de Catalyst son implícitas a las subrutinas de cada paquete que está en el directorio (o paquete) de controladores. Por ejemplo, si editamos el fichero <tt>lib/miproject/Controller/Root.pm</tt> y agregamos el siguiente código:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> libros <span style="color: #339933;">:</span>Global <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$c</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">response</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">body</span> <span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;listado de libros!&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Al ejecutar el servidor de pruebas: <tt>script/miproject_server.pl</tt>; podremos ver la siguiente tabla:</p>
<pre>
[debug] Loaded Private actions:
.----------------------+--------------------------------------+--------------.
| Private              | Class                                | Method       |
+----------------------+--------------------------------------+--------------+
| /default             | miproject::Controller::Root          | default      |
| /end                 | miproject::Controller::Root          | end          |
| /libros              | miproject::Controller::Root          | libros       |
| /index               | miproject::Controller::Root          | index        |
'----------------------+--------------------------------------+--------------'
</pre>
<p>Al cargar la página <a href="http://localhost:3000/libros">http://localhost:3000/libros</a> podemos ver el resultado de la ejecución de la subrutina escrita.</p>
<h3>La vista</h3>
<p>Hemos realizado antes una salida directa desde el controlador, pero lo suyo es crear una vista. El sistema de plantillas de Perl se denomina TT. Es parecido al que se usa en JSP e incluso al que usa la DTL (Django Template Library), pero difiere bastante. Vamos a generar una vista primero:</p>
<pre>
$ script/miproject_create.pl view HTML TT
</pre>
<p>Con esto nuestro directorio de <tt>View</tt> se completa con la generación de un módulo de Perl <tt>HTML.pm</tt>. Ahora creamos una vista con la siguiente información en la ruta <tt>root</tt> con el nombre <tt>listado.tt</tt>:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;h1&gt;Hola mundo!&lt;/h1&gt;
&nbsp;
&lt;p&gt;[% libros %]&lt;/p&gt;</pre></div></div>

<p>Para lo que habrá que cambiar la subrutina escrita anteriormente a la siguiente (también se puede cambiar el nombre y agregar como una completamente nueva):</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> libros <span style="color: #339933;">:</span>Global <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$c</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">stash</span><span style="color: #009900;">&#40;</span>template <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;listado.tt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">stash</span><span style="color: #009900;">&#40;</span>libros <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;no hay libros&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Los modelos</h3>
<p>Tanto Django como Rails, e incluso Doctrine, tienen sistemas de migraciones o sincronización con base de datos. Catalyst no dispone de estos mecanismos. Puede generar sus modelos de una conexión de base de datos con tablas ya creadas, pero no al contrario.</p>
<p>No obstante, su ORM es bastante potente. Por ejemplo, pongamos que creamos una base de datos SQLite (supongamos que en <tt>/tmp/libros.db</tt>):</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">PRAGMA foreign_keys <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">ON</span>;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> libros <span style="color: #66cc66;">&#40;</span>
     id <span style="color: #993333; font-weight: bold;">INTEGER</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span>
     titulo TEXT
<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> autores <span style="color: #66cc66;">&#40;</span>
     id <span style="color: #993333; font-weight: bold;">INTEGER</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span>
     nombre TEXT<span style="color: #66cc66;">,</span>
     apellidos TEXT
<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> libros_autores <span style="color: #66cc66;">&#40;</span>
     libro_id <span style="color: #993333; font-weight: bold;">INTEGER</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> libros<span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #993333; font-weight: bold;">DELETE</span> CASCADE <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #993333; font-weight: bold;">UPDATE</span> CASCADE<span style="color: #66cc66;">,</span>
     autor_id <span style="color: #993333; font-weight: bold;">INTEGER</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> autores<span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #993333; font-weight: bold;">DELETE</span> CASCADE <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #993333; font-weight: bold;">UPDATE</span> CASCADE<span style="color: #66cc66;">,</span>
     <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>libro_id<span style="color: #66cc66;">,</span> autor_id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> libros <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Diseño Ágil con TDD'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> libros <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'No me hagas pensar'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> libros <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Hacking Etico'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> libros <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Perl Best Practices'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> autores <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Carlos'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Ble'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> autores <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Steve'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Krug'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> autores <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Carlos'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Tori'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> autores <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Damian'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Conway'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> libros_autores <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> libros_autores <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> libros_autores <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> libros_autores <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Generamos nuestros modelos con el siguiente comando:</p>
<pre>
$ script/miproject_create.pl model  DB DBIC::Schema \
     MiProject::Schema create=static \
     dbi:SQLite:/tmp/libros.sqlite \
     on_connect_do="PRAGMA foreign_keys = ON"
</pre>
<p>Con esto nos genera un fichero de esquema en el directorio <tt>Model</tt>, con lo que tendremos el acceso a la base de datos configurada. Si quisieramos probar, tan solo necesitaríamos ejecutar lo siguiente. Modificamos la subrutina de nuevo:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> libros <span style="color: #339933;">:</span>Global <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$c</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">stash</span><span style="color: #009900;">&#40;</span>template <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;listado.tt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">stash</span><span style="color: #009900;">&#40;</span>libros <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">model</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'DB::Libro'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">all</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Y también el fichero de plantilla por lo siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;h1&gt;Hola mundo!&lt;/h1&gt;
&nbsp;
[% FOREACH libro IN libros -%]
[% tt_autores = []; tt_autores.push(autor.apellidos) FOREACH autor = libro.autores %]
&lt;p&gt;[% libro.titulo %] - [% tt_autores.join(', ') | html %]&lt;/p&gt;
[% END -%]</pre></div></div>

<p>Por último, agregamos las referencias necesarias en <tt>Libro.pm</tt> y <tt>Autore.pm</tt> (es lo malo del pluralize del inglés cuando se usan palabras castellanas):</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">__PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">many_to_many</span><span style="color: #009900;">&#40;</span>libros <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'libros_autores'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'libro'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Y esto para <tt>Autore.pm</tt>:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">__PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">many_to_many</span><span style="color: #009900;">&#40;</span>autores <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'libros_autores'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'autor'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Con esto ya tendríamos un listado muy simple en funcionamiento. Puedes ver el tutorial completo (con un CRUD de ejemplo y más cosas aún) en la siguiente dirección (en inglés): <a href="http://search.cpan.org/~hkclark/Catalyst-Manual-5.9002/lib/Catalyst/Manual/Tutorial.pod">Tutorial</a>.</p>
<h3>Conclusiones</h3>
<p>El entorno proporciona las bases que proporcionan el resto de frameworks, su simpleza en las rutas y su formato de ORM hace que la programación de elementos sea bastante simple y rápida, no obstante, hay ciertos elementos con los que hay que tratar y revisarlos bien, leer bien la documentación y tratar de entenderlos, si no queremos toparnos con ningún problema a la hora de realizar cualquier entorno.</p>
<p>Personalmente, me ha gustado la experiencia y el entorno en sí, la programación con los módulos de Perl, lo documentado que queda todo si se siguen las líneas y el hecho de que no hace falta escribir mucho código para conseguir que el sistema funcione bien, hacen que sea un framework muy cómodo de utilizar.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2011/11/29/catalyst-framework-web-para-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

