<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[JCastaneyra blog]]></title>
  <link href="http://jcastaneyra.com/atom.xml" rel="self"/>
  <link href="http://jcastaneyra.com/"/>
  <updated>2012-11-19T11:11:10-06:00</updated>
  <id>http://jcastaneyra.com/</id>
  <author>
    <name><![CDATA[Jose Castaneyra]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Raspberry PI primer contacto]]></title>
    <link href="http://jcastaneyra.com/2012/11/19/raspberry-primer-contacto/"/>
    <updated>2012-11-19T12:06:00-06:00</updated>
    <id>http://jcastaneyra.com/2012/11/19/raspberry-primer-contacto</id>
    <content type="html"><![CDATA[<p><img class="right" src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_02.jpg" width="260" height="180">
Por azares del destino tuve un primer contacto con la Raspberry PI, de
hecho yo quería comprarme una, pero no la había encontrado disponible, y
de repente se me aparece una en las manos.</p>

<!--more-->


<h2>Características</h2>

<h3>Primero, ¿Qué es una Raspberry PI?</h3>

<p>De la página de <a href="http://www.raspberrypi.org/faqs">raspberrypi.org</a>:</p>

<blockquote><p>The Raspberry Pi is a credit-card sized computer that plugs into your
TV and a keyboard. It’s a capable little PC which can be used for many
of the things that your desktop PC does, like spreadsheets,
word-processing and games. It also plays high-definition video. We want
to see it being used by kids all over the world to learn programming.</p></blockquote>

<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/Raspi_Iso_Blue.png"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/Raspi_Iso_Blue.png"></a></p>

<h3>¿Qué SoC (System on chip) se usa?</h3>

<blockquote><p>The SoC is a Broadcom BCM2835. This contains an ARM1176JZFS, with
floating point, running at 700Mhz, and a Videocore 4 GPU. The GPU is
capable of BluRay quality playback, using H.264 at 40MBits/s. It has a
fast 3D core accessed using the supplied OpenGL ES2.0 and OpenVG
libraries.</p></blockquote>

<h3>¿Qué tan poderoso es?</h3>

<blockquote><p>The GPU provides Open GL ES 2.0, hardware-accelerated OpenVG, and
1080p30 H.264 high-profile decode.</p>

<p>The GPU is capable of 1Gpixel/s, 1.5Gtexel/s or 24 GFLOPs of general
purpose compute and features a bunch of texture filtering and DMA
infrastructure.</p>

<p>That is, graphics capabilities are roughly equivalent to Xbox 1 level of
performance. Overall real world performance is something like a 300MHz
Pentium 2, only with much, much swankier graphics.</p></blockquote>

<h3>Además</h3>

<ul>
<li>512MB RAM</li>
<li>Arranca desde una SD card, corriendo una distribución de Linux</li>
<li>10/100 BaseT Ethernet socket</li>
<li>Tiene GPIO (General purpose input/output). Son unos pines para poder
programarlos y que interactúen con otros dispositivos, sensores por
ejemplo.</li>
</ul>


<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_02.jpg"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_02.jpg"></a></p>

<h2>Conectando y arrancando la Raspberry PI</h2>

<h3>Lista de dispositivos y cables.</h3>

<ol>
<li>Obvio una Raspberry PI</li>
<li>SD card con distribución de Linux para RPI (esta ya venía incluída)</li>
<li>Teclado y mouse usb</li>
<li>Cable de red</li>
<li>Cable hdmi</li>
<li>Cable de USB a micro USB</li>
<li>Macbook para compartir internet</li>
</ol>


<h3>Prueba</h3>

<p>En mi caso, yo sólo lo quería echar a andar, ya venía con una SD card
con la distribución de linux de Raspberry precargada, por lo que me tuve
que saltar el paso de cargarsela, todo fue más simple. El mouse y
teclado usb que encontré lo tenía guardado entre las cosas viejas que
tenía, en las fotos verán que están todavía con polvo.</p>

<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_mouse.jpg"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_mouse.jpg"></a></p>

<p>La alimentación y la red se la proporcioné desde la macbook, por usb y
compartiendo la red inalámbrica.</p>

<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_con.jpg"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_con.jpg"></a></p>

<p>Por medio de hdmi conecté la TV de la sala para poder ver la salida, y
así se ve cuando está iniciando la raspberry.</p>

<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_init.jpg"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_init.jpg"></a></p>

<p>La primera vez que arranca aparece un menú para configurar ciertas
cosas, a ese menú no le tomé foto pero de las cosas que puedes
configurar es, el layout de tu teclado, habilitar o deshabilitar el
arranque de servidor de ssh, el password de usuario pi, etc. Después de
configurar la Raspberry se reinició.</p>

<p>Luego me apareció el login (el usuario es pi y el password por default
es raspberry) y a lo que inmediatamente después vi el
espacio libre de la SD.</p>

<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_sdsize.jpg"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_sdsize.jpg"></a></p>

<p>Inicialmente la compartición de la red no la configuré bien, por lo que
no tenía salida a internet.</p>

<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_error_net.jpg"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_error_net.jpg"></a></p>

<p>Una vez que configuré bien la compartición de internet en la macbook, lo
que hice en la consola de la raspberry fue correr el comando.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo dhclient eth0</span></code></pre></td></tr></table></div></figure>


<p>Con este comando adquirió una IP dinámica del servidor de DHCP que se
tiene corriendo en la macbook para compartir internet.</p>

<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_dhclient.jpg"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_dhclient.jpg"></a></p>

<p>Una vez hecho esto, ya pude navegar.</p>

<p><a href="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_browsing.jpg"><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/rpi_browsing.jpg"></a></p>

<h2>Final</h2>

<p>Es impresionante lo que han hecho los de Raspberry, tener una
computadora de ese tamaño capaz de reproducir video con calidad de
blueray y además de poder ejecutar juegos que requieran de alto
desempeño gráfico, y por un precio bajo.</p>

<p>La otra parte interesante es para poder progamarla e interfazarla con
dispositivos externos o bien como para enseñar a niños a usar y a
programar una computadora, ahora si no creo que haya tanto problema cuando nos
digan &#8220;tu hijo tiró la computadora, y luego la metio al agua&#8221;.</p>

<h2>LINKS</h2>

<p><a href="http://www.raspberrypi.org/faqs">Raspberry FAQs</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Como incrementar el root EBS de una instancia EC2]]></title>
    <link href="http://jcastaneyra.com/2012/10/22/incrementar-root-ebs-en-ec2/"/>
    <updated>2012-10-22T12:06:00-05:00</updated>
    <id>http://jcastaneyra.com/2012/10/22/incrementar-root-ebs-en-ec2</id>
    <content type="html"><![CDATA[<p><img class="right" src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/aws_logo.jpeg"></p>

<p>Las instancias de EC2 que corren con EBS (Elastic Block Storage) cuando
se crean vienen con un tamaño relativamente pequeño (talvez 8 Gb o un
poco más), ¿que hay si este tamaño lo quiero incrementar?, ¿que tengo que
hacer?</p>

<!--more-->


<p><em>Assumptions</em>: Se asume  de que ya se tienen instaladas y configuradas las herramientas
de línea de comandos de AWS, también cabe mencionar que los comandos que
aquí aparecen les precede el prompt $, en el caso de la instancia remota
también precedido por el host.</p>

<p>Backups: Respaldar información sensible, si se tiene información
importante en /mnt respaldarla ya que esta se perderá al hacer este
proceso.</p>

<p>Al conectarme por ssh a mi instancia y verificar el tamaño del
filesystem veo que tan sólo tiene 7.9G.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ubuntu@ip-10-170-185-61:~$ df -h
</span><span class='line'>Filesystem      Size  Used Avail Use% Mounted on
</span><span class='line'>/dev/xvda1      7.9G  773M  6.8G  11% /
</span><span class='line'>udev            288M  8.0K  288M   1% /dev
</span><span class='line'>tmpfs           119M  160K  118M   1% /run
</span><span class='line'>none            5.0M     0  5.0M   0% /run/lock
</span><span class='line'>none            296M     0  296M   0% /run/shm</span></code></pre></td></tr></table></div></figure>


<p>Siguiendo el tutorial de Eric Hammond de alestic.com (y modificado
ligeramente ya que algunas cosas no corrieron), desde mi lap donde
tengo instalada la herramienta de aws, corro lo siguiente, primero
hay que obtener el id de instancia.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ec2-describe-instances                                                                            
</span><span class='line'>RESERVATION   r-54a9ea12  672080195794    default
</span><span class='line'>INSTANCE  i-2ddc0374  ami-0d153248    ec2-50-18-95-56.us-west-1.compute.amazonaws.com ip-10-170-185-61.us-west-1.compute.internal running jcastaneyra_west    0       t1.micro    2012-10-12T14:47:45+0000    us-west-1c  aki-8d396bc8        monitoring-disabled 50.18.95.56 10.170.185.61           ebs                 paravirtual xen vcdyJ1350053264046  sg-6b43132e default
</span><span class='line'>BLOCKDEVICE   /dev/sda1   vol-3885d716    2012-10-12T14:47:49.000Z    true
</span><span class='line'>TAG   instance    i-2ddc0374  Name    
</span></code></pre></td></tr></table></div></figure>


<p>El id es i-2ddc0374, y el tamaño al que quiero llegar es de 20 Gb, por
lo que voy a correr lo siguiente desde línea de comandos.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ instanceid=i-2ddc0374
</span><span class='line'>$ size=20</span></code></pre></td></tr></table></div></figure>


<p>Hay que obtener el volumen y la zona actual de la instancia.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ oldvolumeid=$(ec2-describe-instances $instanceid | egrep "^BLOCKDEVICE./dev/sda1" | cut -f3)
</span><span class='line'>$ zone=$(ec2-describe-instances $instanceid | egrep "^INSTANCE" | cut -f12)</span></code></pre></td></tr></table></div></figure>


<p>Si se ejecuta el siguiente comando debería aparecer.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ echo "instance $instanceid in $zone with original volume $oldvolumeid"
</span><span class='line'>instance i-2ddc0374 in us-west-1c with original volume vol-3885d716</span></code></pre></td></tr></table></div></figure>


<p>Ahora, hay que detener la instancia (ojo, detener no terminar).</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ec2-stop-instances $instanceid
</span><span class='line'>INSTANCE  i-2ddc0374  running stopping</span></code></pre></td></tr></table></div></figure>


<p>Desasociar el volumen actual de la instancia.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ while ! ec2-detach-volume $oldvolumeid; do sleep 1; done
</span><span class='line'>ATTACHMENT    vol-3885d716    i-2ddc0374  /dev/sda1   detaching   2012-10-12T14:47:49+0000</span></code></pre></td></tr></table></div></figure>


<p>Crear un snapshot del volumen actual.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ snapshotid=$(ec2-create-snapshot $oldvolumeid | cut -f2)
</span><span class='line'>$ while ec2-describe-snapshots $snapshotid | grep -q pending; do sleep 1; done
</span><span class='line'>$ echo "snapshot: $snapshotid"
</span><span class='line'>snapshot: snap-5d91ed71</span></code></pre></td></tr></table></div></figure>


<p>Crear un nuevo volumen basado en el snapshot recien creado.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ newvolumeid=$(ec2-create-volume   --availability-zone $zone   --size $size   --snapshot $snapshotid | cut -f2)
</span><span class='line'>$ echo "new volume: $newvolumeid"
</span><span class='line'>new volume: vol-e6b0e2c8</span></code></pre></td></tr></table></div></figure>


<p>Asociar el nuevo volumen a la instancia.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ec2-attach-volume   --instance $instanceid   --device /dev/sda1   $newvolumeid
</span><span class='line'>ATTACHMENT    vol-e6b0e2c8    i-2ddc0374  /dev/sda1   attaching   2012-10-12T15:25:12+0000
</span><span class='line'>$ while ! ec2-describe-volumes $newvolumeid | grep -q attached; do sleep 1; done</span></code></pre></td></tr></table></div></figure>


<p>Ahora bien, se arranca la instancia.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ec2-start-instances $instanceid
</span><span class='line'>INSTANCE  i-2ddc0374  stopped pending
</span><span class='line'>$ while ! ec2-describe-instances $instanceid | grep -q running; do sleep 1; done</span></code></pre></td></tr></table></div></figure>


<p>Buscamos ahora la nueva ip pública.</p>

<p><em>NOTA</em>: si la instancia tenía una elastic ip
asociada tendremos que volverla a asociar de nuevo.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ec2-describe-instances $instanceid
</span><span class='line'>RESERVATION   r-54a9ea12  672080195794    default
</span><span class='line'>INSTANCE  i-2ddc0374  ami-0d153248    ec2-50-18-24-164.us-west-1.compute.amazonaws.com    ip-10-170-201-117.us-west-1.compute.internal    running jcastaneyra_west    0       t1.micro    2012-10-12T15:26:54+0000    us-west-1c  aki-8d396bc8            monitoring-disabled 50.18.24.164    10.170.201.117          ebs                 paravirtual xen vcdyJ1350053264046  sg-6b43132e default
</span><span class='line'>BLOCKDEVICE   /dev/sda1   vol-e6b0e2c8    2012-10-12T15:25:12.000Z    false
</span><span class='line'>TAG   instance    i-2ddc0374  Name    </span></code></pre></td></tr></table></div></figure>


<p>Al conectarnos de nueva cuenta con ssh vemos que el filesystem ya está
con un nuevo tamaño.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ubuntu@ip-10-170-201-117:~$ df -h
</span><span class='line'>Filesystem      Size  Used Avail Use% Mounted on
</span><span class='line'>/dev/xvda1       20G  777M   18G   5% /
</span><span class='line'>udev            288M  8.0K  288M   1% /dev
</span><span class='line'>tmpfs           119M  160K  118M   1% /run
</span><span class='line'>none            5.0M     0  5.0M   0% /run/lock
</span><span class='line'>none            296M     0  296M   0% /run/shm</span></code></pre></td></tr></table></div></figure>


<p>Después de esto ya podríamos borrar el volumen viejo, e incluso si
estamos seguros que todo quedó bien podríamos también borrar el
snapshot.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ec2-delete-volume $oldvolumeid
</span><span class='line'>VOLUME    vol-3885d716
</span><span class='line'>$ ec2-delete-snapshot $snapshotid
</span><span class='line'>SNAPSHOT  snap-5d91ed71</span></code></pre></td></tr></table></div></figure>


<p>NOTA: Como el nuevo volumen fue creado manualmente, al momento de
terminar la instancia este no se borra automáticamente, creo que hay un
parametro en los atributos de la instancia para volver a habilitar el
borrado automático, pero yo no lo encontré, pero digo, borrarlo
manualmente tampoco me llevó mucho tiempo.</p>

<p>LINKS.</p>

<p><a href="http://alestic.com/2010/02/ec2-resize-running-ebs-root">alestic blog</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Java Testing: Scripts hechos para oracle compatibles con H2]]></title>
    <link href="http://jcastaneyra.com/2012/10/15/java-testing-oracle-scripts-compatible-htwo/"/>
    <updated>2012-10-15T17:30:00-05:00</updated>
    <id>http://jcastaneyra.com/2012/10/15/java-testing-oracle-scripts-compatible-htwo</id>
    <content type="html"><![CDATA[<p><img class="right" src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/jenkins_ci.png" width="320" height="224"></p>

<p>En nuestro desarrollo trabajamos con Oracle, y un tiempo estuvimos
probando directamente con Oracle desde maven con JUnit y Mockito, todo
esto corriendo en un Jenkins, pero
las pruebas tomaban mucho tiempo, varios minutos de hecho, pero en ese
momento tuvimos que hacerlo para validar también los cambios que se
hacían a base de datos, aunque a estas fechas no se bien si esto fue una
buena decisión, posiblemente se pudieron también haber hecho pruebas
sobre estos scripts en una base de datos de oracle aparte, e
independiente de los tests del código.</p>

<p>Después de un rato estas pruebas fueron ligeramente abandonadas, por lo
que tiene meses que no han vuelto a estar en verde, entonces ahora es
necesario retomarlas, pero el hecho de que tome bastante tiempo para
realizarlas y el de tener una BD de Oracle real corriendo en donde se
ejecutan las pruebas, en este caso un servidor de integración, lo hace
un proceso algo engorroso, entonces ahora estamos buscando volver a
trabajar con una DB en memoria para bajarle el tiempo a las pruebas, antes
usábamos hsqldb, y ahora queremos probar H2.</p>

<!--more-->


<p>Para que los scripts hechos para Oracle puedan ser compatibles con H2,
tuvimos que cambiar lo siguiente:</p>

<ol>
<li>VARCHAR2 => VARCHAR</li>
<li>NUMBER => NUMERIC</li>
<li>Un alter table drop con múltiples campos no funciona, por lo que de una
sóla línea de drop borrando varios campos se tuvieron que hacer
varias donde sólo borraran un campo.</li>
<li>CHAR(1) para datos booleanos, para h2 tuvimos que cambiarlo a BOOLEAN.</li>
<li>También, si se hacen foreign keys, los campos con los que se hacen
deben ser no nulos, esta validación la hace H2, curiosamente en
Oracle pasa bien.</li>
<li>El data source quedó de la siguiente manera, pero el truco acá es que
como nosotros hacemos uso de un schema por default, el schema se crea
en la url y ahí se define como schema por default.</li>
</ol>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
</span><span class='line'>      p:driverClassName="org.h2.Driver"
</span><span class='line'>      p:url="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=Oracle;INIT=CREATE
</span><span class='line'>SCHEMA IF NOT EXISTS MYSCHEMA\&gt;
</span><span class='line'>      p:username="sa"
</span><span class='line'>      p:password="" /&gt;</span></code></pre></td></tr></table></div></figure>


<p>La pregunta es ¿Porqué no hicimos compatibles los scripts desde un
principio? Y creo que si lo plantié desde el principio, pero por alguna
razón no le dimos el control adecuado a esto, aunque me parece que
todavía podemos enderezar un poco el camino. La recomendación aquí es,
que mientras más estándar sean los scripts, mejor la adaptación con
cualquier otro motor de BD, incluso para casos como este, de testing.</p>

<p>Por otra parte, todo el set de queries que se tienen que correr, tales
como creación de catálogos, se podrían correr en la url de la configuración de H2,
dentro del parámetro INIT, pero si lo hacíamos así, los queries
empezaban a fallar porque las tablas ya estaban creadas o bien porque se
violaban algunos contraints (los registros ya estaban insertados con una
primer ejecución con alguna conexión previa dentro de las mismas pruebas). Para resolver esta parte creamos un bean de
inicialización.</p>

<p>El bean de inicialización se ve así:</p>

<script src="https://gist.github.com/3862707.js"> </script>


<p>Y del lado de la configuración de data source y de beans:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;bean id="dataSourcePopulator" class="util.DataPopulator"&gt;
</span><span class='line'>        &lt;property name="dataSource" ref="dataSource" /&gt;
</span><span class='line'>    &lt;/bean&gt;</span></code></pre></td></tr></table></div></figure>


<p>Con esto, las pruebas han vuelto a correr rápidamente, ahora están más
cerca del status verde.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Jugando con mi gps logger]]></title>
    <link href="http://jcastaneyra.com/2012/10/07/jugando-con-mi-gps-logger/"/>
    <updated>2012-10-07T22:06:00-05:00</updated>
    <id>http://jcastaneyra.com/2012/10/07/jugando-con-mi-gps-logger</id>
    <content type="html"><![CDATA[<p>Tenía rato que no tocaba mis arduinos, ¡Desde enero! Pero recientemente
en el trabajo empezamos a platicar sobre la plataforma de Arduino, y de
como a algunos les llamaba la atención, por lo que de regreso en casa,
agarré mis arduinos, los desempolvé y los llevé al trabajo para
mostrarlos.</p>

<p><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/logger.jpg" alt="gps
logger" /></p>

<p>Pero precisamente ahora, que estaba por viajar, traté de hacer mi
logger, digo, en realidad es simple lo que hace en general, pero la
diversión ha sido grande.</p>

<!-- more -->


<h2>Materiales y código</h2>

<p>Lo que he usado ha sido:</p>

<ol>
<li>Seeeduino stalker v2.1</li>
<li>GPS bee de Seeedstudio</li>
<li>Lithium Ion Battery de 980 mAh</li>
<li>Solar panel</li>
<li>Micro SD card de 2Gb</li>
<li>Seeeduino stalker enclosure</li>
</ol>


<p><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/logger_components.jpg" alt="componentes" /></p>

<p>El código después de un rato de haber hecho pruebas parece simple, pero
en realidad me encontré con algunos problemas que fui resolviendo sobre
la marcha, problemas, que si me remonto a enero ya había visto y que no
tenía ni idea de como resolver.</p>

<p>El programa utiliza las librerías de TinyGPS, Wire, DS3231 y SD.</p>

<p>La librería de TinyGPS la uso para ayudarme a parsear las sentencias
NMEA que va arrojando el gps, en un principio pensé que esta librería no
me estaba ayudando, ya que el gps tardaba mucho en arrojar sentencias
correctas, claro todas mis pruebas habían sido cerca de la ventana por
lo que el gps no agarraba bien, ahora las pruebas fueron fuera de la
ventana, y puedo decir que funciona muuuuy bien. Algo curioso fue que
estuvo guardando coordenadas mientras estaba dentro del metro,
interesante.</p>

<p>Con la librería de Wire, la verdad no se para que sirve, la habré sacado
de algún sketch que vi en la red y ya no tuve tiempo para probar que
pasaba si la quitaba de mi programa.</p>

<p>La librería DS3231 la utilizo para poderme comunicar con el chip que
trae el seeeduino stalker, este chip es de tiempo real y además de
temperatura, la librería ya la había modificado para que funcionara con
Arduino 1.0, no se si Seeedstudio ya tenga una nueva librería, por lo
que esta vez me fui rápido por lo que ya sabía que funcionaba, la
librería modificada se encuentra
<a href="https://github.com/jcastaneyra/ds3231_library">aquí</a>.</p>

<p>Y por último, la librería SD la utilicé para ir escribiendo a la sd
card.</p>

<p>Algo con lo que me había encontrado también, era que no tenía ni idea de
como convertir en Arduino un flotante a string, para así poderlo mandar
por Serial, con este frágmento de código pude hacerlo:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>float current_lat = -99.123456;
</span><span class='line'>static char dtostrfbuffer[8];
</span><span class='line'>
</span><span class='line'>// convert float to array of charts
</span><span class='line'>dtostrf(current_lat,8, 6, dtostrfbuffer);</span></code></pre></td></tr></table></div></figure>


<p>Aquí está el código completo.</p>

<script src="https://gist.github.com/3845285.js"> </script>


<p>El enclosure al final se veía así.</p>

<p><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/logger_enclosure.jpg" alt="enclosure" /></p>

<h2>Resultados</h2>

<p>Algunos de los datos que arrojó (fecha, tiempo, temperatura, latitude y
longitud):</p>

<p>51012,22431200,28.50,19.389139,-99.187347
51012,22432300,28.50,19.389179,-99.187309
51012,22433300,28.50,19.389219,-99.187302
51012,22434300,28.50,19.389210,-99.187302
51012,22435300,28.50,19.389210,-99.187309
51012,22440300,28.50,19.389191,-99.187279
51012,22441400,28.50,19.389210,-99.187271
51012,22442400,28.50,19.389219,-99.187309</p>

<p>También vi, que para poder mostrar estos datos en un mapa no era
necesario crear un programa, hay una página
<a href="http://www.gpsvisualizer.com/">http://www.gpsvisualizer.com/</a>, en donde
subes tu archivo con coordenadas, aquí también me topé con un problema,
de que mi archivo lo estaba creando con datos de fecha y temperatura al
principio de la línea y las coordenadas al final, gpsvisualizer.com
requiere que el archivo tenga las coordenadas al principio de la línea
(latitud, longitud).</p>

<p><img src="https://s3-us-west-1.amazonaws.com/jcastaneyra-blog/images/gps_logger_map.png" alt="map" /></p>

<h2>Final</h2>

<p>Al final no salieron todos las coordenadas hasta el final de mi viaje, y
eso fue porque la batería del seeeduino se acabó, pero aún así, ha sido
muy divertido ver esto funcionando, yo quería añadirle un xbee para que
en cuanto este se conectara con el xbee coordinador pudiera transmitirle
los datos o de menos su posición actual, pero no lo pude echar a andar y
creo saber porqué, en el código, interactúo con el pin 10 para poder
echar a andar la SD, y ahí precisamente es donde se conecta el xbee
shield, por lo que creo que eso afectaba a que funcionara, por lo que va
a ser necesario conectar el xbee a otros pines, pero eso será para
después.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Testing range between xbee's]]></title>
    <link href="http://jcastaneyra.com/2012/01/03/testing-range-between-xbees/"/>
    <updated>2012-01-03T15:16:00-06:00</updated>
    <id>http://jcastaneyra.com/2012/01/03/testing-range-between-xbees</id>
    <content type="html"><![CDATA[<p>Como hace unos días mencioné de la adquisición de componentes para el Arduino, entre ellos unos Xbee´s de 2 mW y con la antena en chip (Serie 2), me hice a la tarea de probarlos y ver que tanto rango de alcance soportan.</p>

<!-- more -->


<h2>Configuración</h2>

<h3>XBee&#8217;s</h3>

<p>Obviamente, para poder probar la comunicación entre Xbee&#8217;s requerí de un par, uno configurado como Coordinator (el que estaba conectado al Arduino UNO) y el otro como Router (el que se conectó al Seeeduino Stalker), ambos Xbee&#8217;s estaban configurados con el último firmware y con un baudrate de 57600 bps.</p>

<h3>Arduino UNO</h3>

<p>Al Arduino UNO se le conectó el Xbee Coordinator por medio de un shield para Xbee de Seeedstudio.</p>

<p><img class="center" src="http://c243421.r21.cf1.rackcdn.com/xbee_coordinator.jpg"></p>

<p>El código es simple, y se ve a continuación.</p>

<div><script src='https://gist.github.com/1556559.js?file='></script>
<noscript><pre><code>#include &lt;SoftwareSerial.h&gt;

#define RxD 11
#define TxD 12

SoftwareSerial beeSerial =  SoftwareSerial(RxD,TxD);

void setup() {
  beeSerial.begin(57600);
}

void loop() {
  beeSerial.write('1');
  delay(3000);
}</code></pre></noscript></div>


<h3>Seeeduino Stalker</h3>

<p>Al Seeeduino Stalker se le conectó el Xbee Router, y el Buzzer al pin 11. El Stalker como trae su batería recargable y su celda solar, lo puedo tomar e irme a caminar sin ningún problema.</p>

<p><img class="center" src="http://c243421.r21.cf1.rackcdn.com/xbee_router.jpg"></p>

<p>El código de la función de buzz lo tomé de un sitio el cual no recuerdo :) , podríamos decir que estoy reutilizando código.</p>

<div><script src='https://gist.github.com/1556573.js?file='></script>
<noscript><pre><code>
int buzzPin = 11;

void setup() {
  Serial.begin(57600);
  
  pinMode(buzzPin, OUTPUT);
}

void loop() {
  if(Serial.available() &gt; 0) {
    char c = Serial.read();
    if(c == '1') {
      buzz(buzzPin, 2500, 500); // buzz the buzzer on pin 4 at 2500Hz for 500 milliseconds
      Serial.flush();
      delay(2000); // wait a bit between buzzes
    }
  }
}

void buzz(int targetPin, long frequency, long length) {
  long delayValue = 1000000/frequency/2; // calculate the delay value between transitions
  //// 1 second's worth of microseconds, divided by the frequency, then split in half since
  //// there are two phases to each cycle
  long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing
  //// multiply frequency, which is really cycles per second, by the number of seconds to 
  //// get the total number of cycles to produce
 for (long i=0; i &lt; numCycles; i++){ // for the calculated length of time...
    digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram
    delayMicroseconds(delayValue); // wait for the calculated delay value
    digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram
    delayMicroseconds(delayValue); // wait againf or the calculated delay value
  }
}</code></pre></noscript></div>


<h2>Pruebas y Conclusiones</h2>

<p>El alcance que me da es muy poco cuando existen paredes relativamente gruesas, y más aquí en México, que los materiales para paredes suelen ser ladrillo y cemento, al menos eso creo, ya que según pude ver, el alcance suele ser de unos 5 a 10 metros cuando hay paredes, y cuando si hay línea de vista, como de 20 a 30 metros.</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/M3sFa7AnNn0" frameborder="0" allowfullscreen></iframe>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DS3231 Library update for Arduino 1.0]]></title>
    <link href="http://jcastaneyra.com/2012/01/02/ds3231-library-update-for-arduino-1-dot-0/"/>
    <updated>2012-01-02T20:06:00-06:00</updated>
    <id>http://jcastaneyra.com/2012/01/02/ds3231-library-update-for-arduino-1-dot-0</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://c243421.r21.cf1.rackcdn.com/ds3231.jpg">
Ya les había mencionado de mi compra del Seeeduino Stalker, y obviamente empecé a hacer mis primeras pruebas.</p>

<p>Este clon de Arduino trae un RTC DS3231 y en Seeedstudio.com puedes descargar la librería del mismo, pero resulta que con los cambios que se hicieron en el IDE 1.0 de Arduino los sketches que vienen con la librería no funcionan, así que tuve que hacer unos cambios, los cambios en específico sólo se hicieron al archivo DS3231.cpp.</p>

<!--more-->


<p>Toda la librería la subí aquí:</p>

<p><a href="https://github.com/jcastaneyra/ds3231_library">https://github.com/jcastaneyra/ds3231_library</a></p>

<p>Referencias:</p>

<p><a href="http://www.seeedstudio.com/wiki/Seeeduino_Stalker_v2.1">http://www.seeedstudio.com/wiki/Seeeduino_Stalker_v2.1</a>
<a href="http://blog.makezine.com/archive/2011/12/arduino-1-0-is-out-heres-what-you-need-to-know.html">http://blog.makezine.com/archive/2011/12/arduino-1-0-is-out-heres-what-you-need-to-know.html</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Arduino shippings]]></title>
    <link href="http://jcastaneyra.com/2011/12/16/arduino-shippings/"/>
    <updated>2011-12-16T15:56:00-06:00</updated>
    <id>http://jcastaneyra.com/2011/12/16/arduino-shippings</id>
    <content type="html"><![CDATA[<p>Hace unos 2 o 3 años escuché por primera vez sobre Arduino, y se me hizo una plataforma interesante. El punto es que traigo algunos proyectos personales en los cuáles quiero involucrar algo de interacción de software con hardware, por lo que presumo aquí mis más recientes adquisiciones, no entraré mucho en detalle técnico de las características de cada componente ya que estas pueden ser encontradas fácilmente en internet.</p>

<!-- more -->


<p>Lo que compré aquí en México (en el centro, en la calle de República de Uruguay creo).</p>

<ul>
<li>Arduino UNO</li>
</ul>


<p><img class="center" src="http://c243421.r21.cf1.rackcdn.com/arduino_uno.jpg"></p>

<p>Lo siguiente lo compré en <a href="http://www.seeedstudio.com">seeedstudio.com</a></p>

<ul>
<li>Seeeduino stalker kit y que incluye

<ul>
<li>Seeeduino stalker v2.1</li>
<li>Lithium Ion polymer Battery 980mAh</li>
<li>SanDisk microSD Card 2Gb</li>
<li>Mini USB cable</li>
<li>UartSBee</li>
<li>6 pin cable</li>
<li>Seeeduino Stalker v2 enclosure</li>
<li>0.5w Solar Panel</li>
</ul>
</li>
<li>GPS Bee</li>
<li>2 XBee shields</li>
</ul>


<p><img class="center" src="http://c243421.r21.cf1.rackcdn.com/seeeduino_stalker_v21.jpg">
<img class="center" src="http://c243421.r21.cf1.rackcdn.com/gps_bee.jpg"></p>

<p>La siguiente compra fue en <a href="http://www.sparkfun.com">sparkfun.com</a></p>

<ul>
<li>2 XBee 2mW Chip Antenna - Series 2 (ZB)</li>
</ul>


<p><img class="center" src="http://c243421.r21.cf1.rackcdn.com/xbees.jpg"></p>

<p>Aquí una foto con casi todo junto:</p>

<p><img class="center" src="http://c243421.r21.cf1.rackcdn.com/arduino_shoppings.jpg"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Macs usadas en Venta]]></title>
    <link href="http://jcastaneyra.com/2011/09/21/macs-en-venta/"/>
    <updated>2011-09-21T15:45:00-05:00</updated>
    <id>http://jcastaneyra.com/2011/09/21/macs-en-venta</id>
    <content type="html"><![CDATA[<p>Se está llevando, computadoras mac económicas, bara bara, para la hermana(o), para la mamá(papá), para la novia(o), para la abuelita(o), por única ocasión le estamos ofreciendo los siguientes modelos:</p>

<!-- more -->


<p>UPDATE: Ya sólo estoy vendiendo la MacBook Air, de preferencia aquí en
el DF o bien si se requiere hacer envío correría a cuenta del comprador.</p>

<h2> MacBook Air/1.6GHz (2008)</h2>

<ul>
<li>Tipo de Procesador: Core 2 Duo (P7500)</li>
<li>Velocidad de Procesador: 1.6 GHz</li>
<li>Cores: 2</li>
<li>Caches procesador: L1 Cache 32k/32k, L2/L3 Cache 4 MB (on chip)</li>
<li>Geekbench: 2044 (32-bit mode)/2352 (64-bit mode)</li>
<li>RAM: 2 GB of 667 MHz DDR2 SDRAM onboard</li>
<li>Video Card: Intel GMA X3100</li>
<li>VRAM: 144 MB</li>
<li>Display: 13.3 &#8221;</li>
<li>Resolución nativa: 1280x800</li>
<li>Disco duro: 80 GB (4200 RPM)</li>
<li>Red: AirPort Extreme (802.11a/b/g/n) and Bluetooth 2.1+EDR standard</li>
<li>Puertos USB: 1 (2.0)</li>
<li>Tiempo de batería: 5 horas</li>
<li><strong>Sistema Operativo: OS X Lion</strong></li>
<li>Incluye: SuperDrive, convertidor micro-DVI a VGA, convertidor micro-DVI a DVI</li>
</ul>


<p>Nota: El cargador es totalmente nuevo</p>

<p><a href="http://www.everymac.com/systems/apple/macbook-air/stats/macbook-air-core-2-duo-1.6-13-specs.html">Specs en everymac.com</a></p>

<p><strong>Precio MXN $ 9,500.00</strong></p>

<p><a href="http://c243421.r21.cf1.rackcdn.com/macbook_air_01.jpg"><img src="http://c243421.r21.cf1.rackcdn.com/macbook_air_01.jpg" width="320" height="214"></a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mi Blog Con Octopress]]></title>
    <link href="http://jcastaneyra.com/2011/09/19/mi-blog-con-octopress/"/>
    <updated>2011-09-19T12:31:00-05:00</updated>
    <id>http://jcastaneyra.com/2011/09/19/mi-blog-con-octopress</id>
    <content type="html"><![CDATA[<p><img class="left" src="http://c243421.r21.cf1.rackcdn.com/octopress_logo.png">
Después de tanto tiempo heme aquí de vuelta, ha pasado casi un año y medio sin ningún post, por lo que he tenido totalmente abandonado mi blog, he estado trabajando bastante y el tiempo libre se ha reducido a casi nada o bien mi total desorganización me lo ha impedido.</p>

<p>Pues bien, esta vez estoy con una nueva plataforma de blogging (<a href="http://octopress.org">octopress</a>), y está bastante atractiva, veo que muchos ya están sobre esta plataforma, que emoción, y además trabaja con <a href="https://github.com/mojombo/jekyll">jekyll</a> para generar el sitio estático, en los días que siguen iré personalizando mi blog, ya tenía por ahí un estilo muy básico hecho por mi (desde el punto de vista de un desarrollador) con un pequeño ejercicio hecho en sinatra, tendré que aprovecharlo y espero actualizarlo pronto.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Installing RabbitMQ + Stomp in Ubuntu/Mac]]></title>
    <link href="http://jcastaneyra.com/2010/05/30/installing-rabbitmq-stomp-in-ubuntumac/"/>
    <updated>2010-05-30T00:00:00-05:00</updated>
    <id>http://jcastaneyra.com/2010/05/30/installing-rabbitmq-stomp-in-ubuntumac</id>
    <content type="html"><![CDATA[<p><a name="rabbitmq_stomp_english"></a> <a href="#rabbitmq_stomp_spanish">En español</a></p>

<p><img src="http://c243421.r21.cf1.rackcdn.com/RabbitMQLogo-300x79.png" alt="Screenshot of RabbitMQ logo" /></p>

<p>In the project I&#8217;m working now it was needed to have RabbitMQ running with Stomp as a message queue for Orbited, we know that Orbited comes with MorbidQ, but in our system we already had running RabbitMQ and used by other processes, so, two queue systems at the same time were not needed.</p>

<!-- more -->


<p>But, searching for Stomp over RabbitMQ info or some kind of tutorial was difficult and painful, a friend of mine would say &#8220;a real pain in the ass&#8221;, there was info but not too clear. For that reason here is another note to myself, just in case.</p>

<ul>
<li>RabbitMQ 1.6.0 installed, <a href="http://jcastaneyra.com/2009/06/07/instalando-rabbitmq/">here there are some steps</a> to install it.</li>
<li>Mercurial is needed to download Stomp code</li>
<li>Download Stomp code</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>hg clone -r rabbitmq_v1_6_0 http://hg.rabbitmq.com/rabbitmq-stomp</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Compile Stomp (use your RabbitMQ include directory, maybe in Linux /usr/lib/erlang/lib/rabbitmq_server-1.6.0/include, in Mac I have it here /usr/local/lib/erlang/lib/rabbitmq_server-1.6.0/include)</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>cd rabbitmq-stomp
</span><span class='line'>make RABBIT_SERVER_INCLUDE_DIR=/usr/lib/erlang/lib/rabbitmq_server-1.6.0/include</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Copy your compiled Stomp to the Erlang libraries</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo mkdir -p /usr/lib/erlang/lib/rabbitmq-stomp
</span><span class='line'>sudo cp -R * /usr/lib/erlang/lib/rabbitmq-stomp</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Add the Stomp configuration for RabbitMQ (also use your correct directory here, in Linux /usr/lib/erlang/lib/rabbitmq-stomp/ebin and in my Mac /usr/local/lib/erlang/lib/rabbitmq-stomp/ebin)</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo vim /etc/rabbitmq/rabbitmq.conf
</span><span class='line'>
</span><span class='line'>#Add the lines below
</span><span class='line'>NODENAME=rabbit
</span><span class='line'>NODE_IP_ADDRESS=0.0.0.0
</span><span class='line'>NODE_PORT=5672
</span><span class='line'>
</span><span class='line'>LOG_BASE=/var/log/rabbitmq
</span><span class='line'>MNESIA_BASE=/var/lib/rabbitmq/mnesia
</span><span class='line'>
</span><span class='line'>SERVER_START_ARGS='
</span><span class='line'>     -pa /usr/lib/erlang/lib/rabbitmq-stomp/ebin
</span><span class='line'>     -rabbit
</span><span class='line'>       stomp_listeners [{"0.0.0.0",61613}]
</span><span class='line'>       extra_startup_steps [{"STOMP-listeners",rabbit_stomp,kickstart,[]}]'</span></code></pre></td></tr></table></div></figure>


<p>And that&#8217;s it, if you start RabbitMQ will see how STOMP-Listeners are starting (In Linux you maybe will need to stop RabbitMQ with the following command sudo /etc/init.d/rabbitmq-server stop before running the next step, in my Mac I use this command to start RabbitMQ sudo /usr/local/lib/erlang/lib/rabbitmq_server-1.6.0/sbin/rabbitmq-server)</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>deploy@localhost:~$ sudo rabbitmq-server 
</span><span class='line'>RabbitMQ 1.6.0 (AMQP 8-0)
</span><span class='line'>Copyright (C) 2007-2009 LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd.
</span><span class='line'>Licensed under the MPL.  See http://www.rabbitmq.com/
</span><span class='line'>
</span><span class='line'>node        : rabbit@localhost
</span><span class='line'>log         : /var/log/rabbitmq/rabbit.log
</span><span class='line'>sasl log    : /var/log/rabbitmq/rabbit-sasl.log
</span><span class='line'>database dir: /var/lib/rabbitmq/mnesia/rabbit
</span><span class='line'>
</span><span class='line'>starting database             ...done
</span><span class='line'>starting core processes       ...done
</span><span class='line'>starting recovery             ...done
</span><span class='line'>starting persister            ...done
</span><span class='line'>starting guid generator       ...done
</span><span class='line'>starting builtin applications ...done
</span><span class='line'>starting TCP listeners        ...done
</span><span class='line'>starting STOMP-listeners      ...done
</span><span class='line'>
</span><span class='line'>broker running</span></code></pre></td></tr></table></div></figure>


<p><a name="rabbitmq_stomp_spanish"></a> <a href="#rabbitmq_stomp_english">In english</a></p>

<p><img src="http://c243421.r21.cf1.rackcdn.com/RabbitMQLogo-300x79.png" alt="Screenshot of RabbitMQ logo" /></p>

<p>En el proyecto en el que estoy trabajando era necesario tener corriendo RabbitMQ con Stomp para poder hacer conexiones con Orbited, Orbited ya incluye MorbidQ, pero en este caso ya teníamos corriendo RabbitMQ para otros procesos y no era necesario tener un segundo sistema de queues.</p>

<p>Sorprendentemente, encontrar información de cómo agregar Stomp a RabbitMQ resultó algo doloroso, si había información pero como que no indicaba bien que pasos seguir. Entonces como parte de mis notas personales estoy agregando esta receta por si se llega a ofrecer de nueva cuenta.</p>

<ul>
<li>Tener instalado RabbitMQ 1.6.0, <a href="http://jcastaneyra.com/2009/06/07/instalando-rabbitmq/">aquí hay unos pasos</a> para instalarlo.</li>
<li>Tener instalado Mercurial para bajar el código de Stomp</li>
<li>Bajar el código de Stomp</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>hg clone -r rabbitmq_v1_6_0 http://hg.rabbitmq.com/rabbitmq-stomp</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Compilar Stomp (apuntando al directorio de include donde se encuentra RabbitMQ, en Linux /usr/lib/erlang/lib/rabbitmq_server-1.6.0/include y en Mac yo lo tengo en /usr/local/lib/erlang/lib/rabbitmq_server-1.6.0/include)</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>cd rabbitmq-stomp
</span><span class='line'>make RABBIT_SERVER_INCLUDE_DIR=/usr/lib/erlang/lib/rabbitmq_server-1.6.0/include</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Copiar Stomp compilado al directorio de librerías de Erlang</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo mkdir -p /usr/lib/erlang/lib/rabbitmq-stomp
</span><span class='line'>sudo cp -R * /usr/lib/erlang/lib/rabbitmq-stomp</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Agregar la configuración de Stomp a RabbitMQ (también apuntar al directorio correcto en la configuración, en Linux /usr/lib/erlang/lib/rabbitmq-stomp/ebin y en mi Mac /usr/local/lib/erlang/lib/rabbitmq-stomp/ebin)</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo vim /etc/rabbitmq/rabbitmq.conf
</span><span class='line'>
</span><span class='line'>#Add the lines below
</span><span class='line'>NODENAME=rabbit
</span><span class='line'>NODE_IP_ADDRESS=0.0.0.0
</span><span class='line'>NODE_PORT=5672
</span><span class='line'>
</span><span class='line'>LOG_BASE=/var/log/rabbitmq
</span><span class='line'>MNESIA_BASE=/var/lib/rabbitmq/mnesia
</span><span class='line'>
</span><span class='line'>SERVER_START_ARGS='
</span><span class='line'>  -pa /usr/lib/erlang/lib/rabbitmq-stomp/ebin
</span><span class='line'>  -rabbit
</span><span class='line'>    stomp_listeners [{"0.0.0.0",61613}]
</span><span class='line'>    extra_startup_steps [{"STOMP-listeners",rabbit_stomp,kickstart,[]}]'</span></code></pre></td></tr></table></div></figure>


<p>Listo, si intentan arrancar RabbitMQ se verá que dice que está levantando los STOMP-Listeners (En Linux talvez necesiten terminar el proceso con sudo /etc/init.d/rabbitmq-server stop antes de correr lo siguiente, y en Mac para levantar el servidor yo ejecuto sudo /usr/local/lib/erlang/lib/rabbitmq_server-1.6.0/sbin/rabbitmq-server)</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>deploy@localhost:~$ sudo rabbitmq-server 
</span><span class='line'>RabbitMQ 1.6.0 (AMQP 8-0)
</span><span class='line'>Copyright (C) 2007-2009 LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd.
</span><span class='line'>Licensed under the MPL.  See http://www.rabbitmq.com/
</span><span class='line'>
</span><span class='line'>node        : rabbit@localhost
</span><span class='line'>log         : /var/log/rabbitmq/rabbit.log
</span><span class='line'>sasl log    : /var/log/rabbitmq/rabbit-sasl.log
</span><span class='line'>database dir: /var/lib/rabbitmq/mnesia/rabbit
</span><span class='line'>
</span><span class='line'>starting database             ...done
</span><span class='line'>starting core processes       ...done
</span><span class='line'>starting recovery             ...done
</span><span class='line'>starting persister            ...done
</span><span class='line'>starting guid generator       ...done
</span><span class='line'>starting builtin applications ...done
</span><span class='line'>starting TCP listeners        ...done
</span><span class='line'>starting STOMP-listeners      ...done
</span><span class='line'>
</span><span class='line'>broker running</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bundler gem and Daemons error (The default Gemfile was not found)]]></title>
    <link href="http://jcastaneyra.com/2010/02/12/bundler-gem-and-daemons-error-the-default-gemfile-was-not-found/"/>
    <updated>2010-02-12T00:00:00-06:00</updated>
    <id>http://jcastaneyra.com/2010/02/12/bundler-gem-and-daemons-error-the-default-gemfile-was-not-found</id>
    <content type="html"><![CDATA[<p><a name="bundler_gem_daemons_error_english"></a> (<a href="#bundler_gem_daemons_error_spanish">En español</a>)</p>

<p>Some days ago we deployed an application with rails, in this application we are using some daemons (with daemons gem) to take care about some business processes, and recently to have more control with all gems used by our application we started to use bundler.</p>

<p>Almost all was done, so, at the moment to start the daemons, we get the following error:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/usr/lib/ruby/gems/1.8/gems/bundler-0.9.3/lib/bundler.rb:122:in `default_gemfile': The default Gemfile was not found (Bundler::GemfileNotFound)
</span><span class='line'>  from /usr/lib/ruby/gems/1.8/gems/bundler-0.9.3/lib/bundler.rb:64:in `setup'</span></code></pre></td></tr></table></div></figure>




<!-- more -->


<p>So, looking for this error in google we didn&#8217;t get anything, and looking into the bundler gem code the solution to this problems was:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;BUNDLE_GEMFILE&#39;</span><span class="o">]</span> <span class="o">||=</span> <span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="no">Dir</span><span class="o">.</span><span class="n">pwd</span><span class="p">,</span> <span class="s1">&#39;Gemfile&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>The complete daemon code here:</p>

<div><script src='https://gist.github.com/302390.js?file='></script>
<noscript><pre><code>require 'rubygems'
require 'daemons'
#require File.join(File.dirname(__FILE__), 'daemons_extension')

ENV['RAILS_ENV'] ||= 'development'
ENV['BUNDLE_GEMFILE'] ||= File.join(Dir.pwd, 'Gemfile')

options = {
  :app_name  =&gt; 'mail_consumer',
  :dir_mode  =&gt; :script,
  :dir       =&gt; '../log',
  :backtrace =&gt; true,
  :mode      =&gt; :load,
  :monitor   =&gt; true
}

Daemons.run(File.join(File.dirname(__FILE__), 'mail_consumer.rb'), options)
</code></pre></noscript></div>


<p><a name="bundler_gem_daemons_error_spanish"></a> (<a href="#bundler_gem_daemons_error_english">In english</a>)</p>

<p>Hace algunos días hicimos el deployment de una aplicación con rails, con esta aplicación corremos algunos demonios (con la gema daemons) que se hacen cargo de algunas operaciones de negocio, y recientemente para tener más control de las gemas que utilizamos empezamos a usar bundler.</p>

<p>Ya se tenía todo listo, al momento de correr los demonios nos encontramos con el siguiente error:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="sr">/usr/</span><span class="n">lib</span><span class="o">/</span><span class="n">ruby</span><span class="o">/</span><span class="n">gems</span><span class="o">/</span><span class="mi">1</span><span class="o">.</span><span class="mi">8</span><span class="o">/</span><span class="n">gems</span><span class="o">/</span><span class="n">bundler</span><span class="o">-</span><span class="mi">0</span><span class="o">.</span><span class="mi">9</span><span class="o">.</span><span class="mi">3</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">bundler</span><span class="o">.</span><span class="n">rb</span><span class="p">:</span><span class="mi">122</span><span class="ss">:in</span> <span class="sb">`default_gemfile&#39;: The default Gemfile was not found (Bundler::GemfileNotFound)</span>
</span><span class='line'><span class="sb"> from /usr/lib/ruby/gems/1.8/gems/bundler-0.9.3/lib/bundler.rb:64:in `</span><span class="n">setup</span><span class="err">&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Cabe mencionar que buscando en google no se encontró nada de como resolver el problema, así que indagando un poco en el código de bundler, llegamos a la siguiente solución, que fue agregar la siguiente línea al código que levanta nuestro demonio.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;BUNDLE_GEMFILE&#39;</span><span class="o">]</span> <span class="o">||=</span> <span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="no">Dir</span><span class="o">.</span><span class="n">pwd</span><span class="p">,</span> <span class="s1">&#39;Gemfile&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>El código completo del demonio es el siguiente:</p>

<div><script src='https://gist.github.com/302390.js?file='></script>
<noscript><pre><code>require 'rubygems'
require 'daemons'
#require File.join(File.dirname(__FILE__), 'daemons_extension')

ENV['RAILS_ENV'] ||= 'development'
ENV['BUNDLE_GEMFILE'] ||= File.join(Dir.pwd, 'Gemfile')

options = {
  :app_name  =&gt; 'mail_consumer',
  :dir_mode  =&gt; :script,
  :dir       =&gt; '../log',
  :backtrace =&gt; true,
  :mode      =&gt; :load,
  :monitor   =&gt; true
}

Daemons.run(File.join(File.dirname(__FILE__), 'mail_consumer.rb'), options)
</code></pre></noscript></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Table names case insensitive for MySQL Linux]]></title>
    <link href="http://jcastaneyra.com/2010/01/07/table-names-case-insensitive-for-mysql-linux/"/>
    <updated>2010-01-07T00:00:00-06:00</updated>
    <id>http://jcastaneyra.com/2010/01/07/table-names-case-insensitive-for-mysql-linux</id>
    <content type="html"><![CDATA[<p>Hola a todos, feliz año 2010, que tal se pasaron estas fechas? descansaron bastante? Pues yo más o menos, unos ratos descansaba y otros trabajaba, y para variar me encontré con esto en el trabajo.</p>

<p>Resulta que estaba montando un servidor de Weblogic y MySQL en Linux, para instalar una aplicación que originalmente estaba con Weblogic y Oracle, y resulta que al cargar las tablas de esta aplicación en MySQL empecé a encontrarme problemas con los nombres de las tablas (entre otras cosas, como los tipos de datos entre Oracle y MySQL), yo no sabía que MySQL por default en Linux es case sensitive, por lo que me di a la tarea de investigar y buscar como deshabilitar esta función.</p>

<!-- more -->


<p>Es necesario editar el archivo my.cnf que se puede encontrar en /etc o bien en /etc/mysql, e inmediatamente después de la sección [mysqld], agregar lo siguiente:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>lower_case_table_names=1</span></code></pre></td></tr></table></div></figure>


<p>Guardamos el archivo y reiniciamos MySQL, con esto al momento de crear nuevas tablas estas se harán en minúsculas, y ya no tendremos problemas de si son mayúsculas o minúsculas.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Como crear un archivo zip con ruby]]></title>
    <link href="http://jcastaneyra.com/2009/11/16/como-crear-un-archivo-zip-con-ruby/"/>
    <updated>2009-11-16T00:00:00-06:00</updated>
    <id>http://jcastaneyra.com/2009/11/16/como-crear-un-archivo-zip-con-ruby</id>
    <content type="html"><![CDATA[<p>Hace unos días me encontré con el problema de generar archivos Zip que contuvieran archivos de un curso de SCORM, ¿Cómo hacerlo?, lo primero que me vino a la mente fue Ruby!!!</p>

<!-- more -->


<p>La gema que me sirvió para esto fue rubyzip, y con el siguiente fragmento de código se realizaron los archivos zip:</p>

<div><script src='https://gist.github.com/235735.js?file='></script>
<noscript><pre><code>require 'rubygems'
require 'zip/zip'
require 'zip/zipfilesystem'

current_path = Dir.pwd
      
scorm_file = current_path + &quot;/&quot; + tmp_dir + '/' + course + &quot;/#{scorm_module}.zip&quot;
# module_path is where scorm files are (files to zip)
Dir.chdir(module_path)
files_to_zip = Dir[&quot;**/*&quot;]
      
Zip::ZipFile.open(scorm_file, Zip::ZipFile::CREATE) do |zipfile|
  files_to_zip.each { |f| zipfile.add( f, f) }
end
      
Dir.chdir(current_path)</code></pre></noscript></div>


<p>Espero que les sirva como a mi.</p>

<p>Links:</p>

<ol>
<li><a href="http://ruby-doc.org/core/classes/Dir.html">http://ruby-doc.org/core/classes/Dir.html</a></li>
<li><a href="http://ruby-doc.org/core/classes/FileUtils.html">http://ruby-doc.org/core/classes/FileUtils.html</a></li>
<li><a href="http://rubyzip.sourceforge.net/">http://rubyzip.sourceforge.net/</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Etiquetando código en git/Tagging code in git]]></title>
    <link href="http://jcastaneyra.com/2009/11/05/etiquetando-codigo-en-gittagging-code-in-git/"/>
    <updated>2009-11-05T00:00:00-06:00</updated>
    <id>http://jcastaneyra.com/2009/11/05/etiquetando-codigo-en-gittagging-code-in-git</id>
    <content type="html"><![CDATA[<p><a name="tagging_code_git_spanish"><strong>Etiquetando código en git</strong></a> (<a href="#tagging_code_git_english">English</a>)</p>

<p>Resulta que al estar trabajando con nuestro código queremos marcar o etiquetar nuestro código en cierto momento de tiempo, algo así como versionar nuestro código.</p>

<p>A decir verdad no soy un experto en git, pero esto es lo que me ha funcionado. Primero que nada tendríamos que etiquetar nuestro código (ponerle una marca), para esto usamos el comando git tag:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git tag -a -m "My old and ugly style" old_style</span></code></pre></td></tr></table></div></figure>




<!-- more -->


<p>Para ver nuestros tags locales tenemos que ejecutar</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git tag -l</span></code></pre></td></tr></table></div></figure>


<p>Pero como le agregué una descripción a mi tag ejecuto lo siguiente para poder ver el tag junto con su descripción</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git tag -l -n1</span></code></pre></td></tr></table></div></figure>


<p>Con esto tenemos agregado el tag localmente, pero como yo trabajo con un repositorio remoto, para subir mi tag tengo que hacer</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git push origin --tags</span></code></pre></td></tr></table></div></figure>


<p>Ya tengo una etiqueta en mi código, ahora supongamos que pasan dos semanas y que quiero ver algo en mi viejo y feo estilo, sólo tendría que hacer lo siguiente:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git checkout -f -b mybranch old_style</span></code></pre></td></tr></table></div></figure>


<p>Así tendría un nuevo branch con mi código que tiene la etiqueta de old_style.</p>

<p>Links:</p>

<ol>
<li><a href="http://ariejan.net/2009/09/05/git-tag-mini-cheat-sheet-revisited/?doing_wp_cron">http://ariejan.net/2009/09/05/git-tag-mini-cheat-sheet-revisited/?doing_wp_cron</a></li>
<li><a href="http://polywww.in2p3.fr/~gaycken/Calice/Software/my_git_workflow.html">http://polywww.in2p3.fr/~gaycken/Calice/Software/my_git_workflow.html</a></li>
</ol>


<p><a name="tagging_code_git_english"><strong>Tagging code in git</strong></a> (<a href="#tagging_code_git_spanish">Español</a>)</p>

<p>When we are working with our code in some time of the project we want to mark or tag the code in order to have control until that time of the project and code, something like versioning.</p>

<p>I&#8217;m not a git expert, but this worked for me. First of all, we need to tag our code, use this command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git tag -a -m "My old and ugly style" old_style</span></code></pre></td></tr></table></div></figure>


<p>In order to see all local tags</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git tag -l</span></code></pre></td></tr></table></div></figure>


<p>Since I added a description to my tag it&#8217;s needed to execute the following to see the description</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git tag -l -n1</span></code></pre></td></tr></table></div></figure>


<p>Until now we have this tag added locally, but if we work with a remote repository we are going to push the tag</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git push origin --tags</span></code></pre></td></tr></table></div></figure>


<p>I already have this tag in my code, now suppose that some weeks have been passed and you want to see something in your old and ugly style, you would need to do:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git checkout -f -b mybranch old_style</span></code></pre></td></tr></table></div></figure>


<p>With this command you would have a new branch with the code tagged with old_style.</p>

<p>Links:</p>

<ol>
<li><a href="http://ariejan.net/2009/09/05/git-tag-mini-cheat-sheet-revisited/?doing_wp_cron">http://ariejan.net/2009/09/05/git-tag-mini-cheat-sheet-revisited/?doing_wp_cron</a></li>
<li><a href="http://polywww.in2p3.fr/~gaycken/Calice/Software/my_git_workflow.html">http://polywww.in2p3.fr/~gaycken/Calice/Software/my_git_workflow.html</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Enviando correo de manera asíncrona en Rails usando Workling, Workling-Mailer y RabbitMQ]]></title>
    <link href="http://jcastaneyra.com/2009/06/10/enviando-correo-de-manera-asincrona-en-rails-usando-workling-workling-mailer-y-rabbitmq/"/>
    <updated>2009-06-10T00:00:00-05:00</updated>
    <id>http://jcastaneyra.com/2009/06/10/enviando-correo-de-manera-asincrona-en-rails-usando-workling-workling-mailer-y-rabbitmq</id>
    <content type="html"><![CDATA[<p><a name="async_mailer_spanish"><strong>Enviando correo de manera asíncrona en Rails usando Workling, Workling-Mailer y RabbitMQ</strong></a> (<a href="#async_mailer_english">English</a>)</p>

<p>El trabajar con message queues es bastante interesante, ya que podemos mandar procesos al background y que estos sean procesados de manera asíncrona, un ejemplo podría ser el envío de correos, aunque también podría servir para realizar otras tareas, por ejemplo, como el envío de mensajes sms, generación de reportes, generación de pdf&#8217;s, etc.</p>

<p>En esta ocasión les quiero presentar como enviar correos de manera asíncrona haciendo una aplicación sencilla haciendo uso de los puglins Workling y workling-mailer y del sistema RabbitMQ, en teoría, con esto se podría ajustar esta solución fácilmente a cualquier otro proceso que se quiera realizar de manera asíncrona.</p>

<!-- more -->


<h2>Aplicación base</h2>

<p>Se crea una aplicación básica con restful_authentication, y con la opción de activación.</p>

<p>Lo primero que hacemos es crear la aplicación en rails</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rails mail_async_example -d mysql
</span><span class='line'>
</span><span class='line'>rm public/index.html
</span><span class='line'>
</span><span class='line'>script/plugin install git://github.com/technoweenie/restful-authentication.git
</span><span class='line'>
</span><span class='line'>script/generate authenticated user sessions --include-activation</span></code></pre></td></tr></table></div></figure>


<p>Creamos nuestra base de datos y migramos</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rake db:create
</span><span class='line'>
</span><span class='line'>rake db:migrate</span></code></pre></td></tr></table></div></figure>


<p>Y hacemos unos pequeños cambios al código de la aplicación para enviar correo según las instrucciones de restful_authentication, así que agregamos lo suguiente:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1">#config/routes.rb</span>
</span><span class='line'><span class="n">map</span><span class="o">.</span><span class="n">activate</span> <span class="s1">&#39;activate/:activation_code&#39;</span><span class="p">,</span> <span class="ss">:controller</span> <span class="o">=&gt;</span> <span class="s1">&#39;users&#39;</span><span class="p">,</span> <span class="ss">:action</span> <span class="o">=&gt;</span> <span class="s1">&#39;activate&#39;</span><span class="p">,</span> <span class="ss">:activation_code</span> <span class="o">=&gt;</span> <span class="kp">nil</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#config/environment.rb</span>
</span><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">active_record</span><span class="o">.</span><span class="n">observers</span> <span class="o">=</span> <span class="ss">:user_observer</span>
</span></code></pre></td></tr></table></div></figure>


<p>Con esto ya tendríamos nuestra aplicación básica la cuál podríamos probar de inmediato apuntando en el browser a http://localhost:3000/signup</p>

<p>Y agregando algunas cosillas extras, a app/controller/application_controller.rb agregamos la línea:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="kp">include</span> <span class="no">AuthenticatedSystem</span>
</span></code></pre></td></tr></table></div></figure>


<p>Esta misma línea que agregamos al Application controller la removemos de app/controller/sessions_controller.rb y de app/controllers/users_controller.rb</p>

<p>Y creamos un nuevo controlador</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">script</span><span class="o">/</span><span class="n">generate</span> <span class="n">controller</span> <span class="n">portal</span> <span class="n">index</span>
</span></code></pre></td></tr></table></div></figure>


<p>Modificamos config/routes.rb para agregar al último como página root</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">map</span><span class="o">.</span><span class="n">root</span> <span class="ss">:controller</span> <span class="o">=&gt;</span> <span class="s2">&quot;portal&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Por último agregamos un layout para nuestra aplicación:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="x">&lt;!--app/views/layouts/application.html.erb--!&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="x">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
</span><span class='line'><span class="x">       &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="x">&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;</span>
</span><span class='line'><span class="x">&lt;head&gt;</span>
</span><span class='line'><span class="x">  &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;charset=UTF-8&quot; /&gt;</span>
</span><span class='line'><span class="x">  &lt;title&gt;Contracts: </span><span class="cp">&lt;%=</span> <span class="n">controller</span><span class="o">.</span><span class="n">action_name</span> <span class="cp">%&gt;</span><span class="x">&lt;/title&gt;</span>
</span><span class='line'><span class="x">  </span><span class="cp">&lt;%=</span> <span class="n">stylesheet_link_tag</span> <span class="s1">&#39;scaffold&#39;</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">&lt;/head&gt;</span>
</span><span class='line'><span class="x">&lt;body&gt;</span>
</span><span class='line'><span class="cp">&lt;%</span> <span class="k">if</span> <span class="n">current_user</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">   </span><span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="s1">&#39;Logout&#39;</span><span class="p">,</span> <span class="n">logout_path</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="cp">&lt;%</span> <span class="k">else</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">   </span><span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="s1">&#39;Login&#39;</span><span class="p">,</span> <span class="n">login_path</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">   </span><span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="s1">&#39;Sign up&#39;</span><span class="p">,</span> <span class="n">signup_path</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="cp">&lt;%</span> <span class="k">end</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'>
</span><span class='line'><span class="cp">&lt;%</span> <span class="o">[</span><span class="ss">:error</span><span class="p">,</span> <span class="ss">:warning</span><span class="p">,</span> <span class="ss">:notice</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">level</span><span class="o">|</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">flash</span><span class="o">[</span><span class="n">level</span><span class="o">]</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">      &lt;div class=&quot;flash </span><span class="cp">&lt;%=</span> <span class="n">level</span><span class="o">.</span><span class="n">to_s</span> <span class="cp">-%&gt;</span><span class="x">&quot;&gt;</span><span class="cp">&lt;%=</span> <span class="n">flash</span><span class="o">[</span><span class="n">level</span><span class="o">]</span> <span class="cp">-%&gt;</span><span class="x">&lt;/div&gt;</span>
</span><span class='line'><span class="x">  </span><span class="cp">&lt;%</span> <span class="k">end</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'><span class="cp">&lt;%</span> <span class="k">end</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'>
</span><span class='line'><span class="cp">&lt;%=</span> <span class="k">yield</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'>
</span><span class='line'><span class="x">&lt;/body&gt;</span>
</span><span class='line'><span class="x">&lt;/html&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Instalando amqp, workling y workling_mailer</h2>

<p>Ahora bien, antes de instalar Workling, para poder trabajar con RabbitMQ es necesario instalar la gema de amqp, esta gema requiere también de la gema de EventMachine, por lo que al instalar amqp también instalará EventMachine.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="x">gem sources -a http://gems.github.com/</span>
</span><span class='line'><span class="x">sudo gem install tmm1-amqp --no-rdoc --no-ri</span>
</span></code></pre></td></tr></table></div></figure>


<p>Vemos nuestro listado de gemas</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="x">sudo gem list</span>
</span></code></pre></td></tr></table></div></figure>


<p>Ahora si, a instalar workling y workling_mailer</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="x">script/plugin install git://github.com/purzelrakete/workling.git</span>
</span><span class='line'>
</span><span class='line'><span class="x">script/plugin install git://github.com/langalex/workling_mailer.git</span>
</span></code></pre></td></tr></table></div></figure>


<p>Para poder utilizar workling con RabbitMQ agregamos al final de config/environment.rb</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">after_initialize</span> <span class="k">do</span>
</span><span class='line'><span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">.</span><span class="n">invoker</span> <span class="o">=</span> <span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">::</span><span class="no">Invokers</span><span class="o">::</span><span class="no">EventmachineSubscriber</span>
</span><span class='line'><span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">.</span><span class="n">dispatcher</span> <span class="o">=</span> <span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">::</span><span class="no">Runners</span><span class="o">::</span><span class="no">ClientRunner</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">.</span><span class="n">dispatcher</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="no">Workling</span><span class="o">::</span><span class="no">Clients</span><span class="o">::</span><span class="no">AmqpClient</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Posteriormente en app/models/user_mailer.rb añadimos</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="kp">include</span> <span class="no">AsynchMail</span>
</span></code></pre></td></tr></table></div></figure>


<p>A la fecha de hoy el plugin de workling tiene un pequeño issue, para resolverlo hacemos lo siguiente en el archivo lib/workling/clients/memcache_queue_client.rb y verificar que contiene:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;memcache&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Al principio del archivo, si no lo tienes agrégalo.</p>

<p>Como el amqp corre sobre un ciclo de EventMachine es necesario correr nuestra aplicación con Thin, ya que este servidor soporta EventMachine sin ningún problema. Para instalar Thin corremos</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">sudo</span> <span class="n">gem</span> <span class="n">install</span> <span class="n">thin</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">rdoc</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">ri</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Instalando RabbitMQ</h2>

<p>Checar la instalación <a href="http://jcastaneyra.com/2009/06/07/instalando-rabbitmq/">aquí</a></p>

<h2>A correr todos</h2>

<p>Nos aseguramos de que el RabbitMQ esté corriendo.</p>

<p>Iniciamos el cliente de workling</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">script</span><span class="o">/</span><span class="n">workling_client</span> <span class="n">start</span>
</span></code></pre></td></tr></table></div></figure>


<p>E iniciamos el servidor thin</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">thin</span> <span class="n">start</span>
</span></code></pre></td></tr></table></div></figure>


<p>Apuntamos nuestro browser a http://localhost:3000 y nos registramos con un usuario, al verificar el log de desarrollo veremos que el correo ahora es enviado después de todas las últimas operaciones registradas en el log. Podemos probar quitando la línea de include AsynchMail del UserMailer y ver lo que hace, o bien haciendo nuevo proceso que sea pesado y que se realice en background.</p>

<p>Referencias:</p>

<ol>
<li><a href="http://github.com/christospappas/workling/commit/063b9849b32e0c6140a5ecdb254357770d9bd28f">http://github.com/christospappas/workling/commit/063b9849b32e0c6140a5ecdb254357770d9bd28f</a></li>
<li><a href="http://github.com/purzelrakete/workling/">http://github.com/purzelrakete/workling/</a></li>
<li><a href="http://github.com/langalex/workling_mailer/">http://github.com/langalex/workling_mailer/</a></li>
<li><a href="http://github.com/tmm1/amqp/">http://github.com/tmm1/amqp/</a></li>
<li><a href="http://github.com/technoweenie/restful-authentication/">http://github.com/technoweenie/restful-authentication/</a></li>
<li><a href="http://www.rabbitmq.com">http://www.rabbitmq.com</a></li>
<li><a href="http://code.macournoyer.com/thin/">http://code.macournoyer.com/thin/</a></li>
<li><a href="http://jcastaneyra.com/2009/06/07/instalando-rabbitmq/">Instalando RabbitMQ</a></li>
</ol>


<p><a name="async_mailer_english"><strong>Sending mails in asynchronous way in Rails using Workling, Workling-Mailer and RabbitMQ</strong></a> (<a href="#async_mailer_spanish">Español</a>)</p>

<p>Working with message queues is so interesting, since we can put processes in the background in order to be processed in asynchronous way, imagine this to send several mails, or maybe for heavy tasks as sms messages, report generation, pdf generation, etc.</p>

<p>So, with this post I want you to show how to send mails in asynchronous way, we are going to make a small application using Workling, Workling-mailer and as message queue RabbitMQ, actually we could adjust this solution to any other problem with async process requirement.</p>

<h2>Base application</h2>

<p>We create a simple application with restful_authentication and activation option.</p>

<p>First of all we create the rails app</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">rails</span> <span class="n">mail_async_example</span> <span class="o">-</span><span class="n">d</span> <span class="n">mysql</span>
</span><span class='line'>
</span><span class='line'><span class="n">rm</span> <span class="kp">public</span><span class="o">/</span><span class="n">index</span><span class="o">.</span><span class="n">html</span>
</span><span class='line'>
</span><span class='line'><span class="n">script</span><span class="o">/</span><span class="n">plugin</span> <span class="n">install</span> <span class="n">git</span><span class="ss">:/</span><span class="o">/</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">technoweenie</span><span class="o">/</span><span class="n">restful</span><span class="o">-</span><span class="n">authentication</span><span class="o">.</span><span class="n">git</span>
</span><span class='line'>
</span><span class='line'><span class="n">script</span><span class="o">/</span><span class="n">generate</span> <span class="n">authenticated</span> <span class="n">user</span> <span class="n">sessions</span> <span class="o">--</span><span class="kp">include</span><span class="o">-</span><span class="n">activation</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now with rake we create and migrate DB</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">rake</span> <span class="n">db</span><span class="ss">:create</span>
</span><span class='line'>
</span><span class='line'><span class="n">rake</span> <span class="n">db</span><span class="ss">:migrate</span>
</span></code></pre></td></tr></table></div></figure>


<p>Following the restful_authentication instructions to send mail we add this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1">#config/routes.rb</span>
</span><span class='line'><span class="n">map</span><span class="o">.</span><span class="n">activate</span> <span class="s1">&#39;activate/:activation_code&#39;</span><span class="p">,</span> <span class="ss">:controller</span> <span class="o">=&gt;</span> <span class="s1">&#39;users&#39;</span><span class="p">,</span> <span class="ss">:action</span> <span class="o">=&gt;</span> <span class="s1">&#39;activate&#39;</span><span class="p">,</span> <span class="ss">:activation_code</span> <span class="o">=&gt;</span> <span class="kp">nil</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#config/environment.rb</span>
</span><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">active_record</span><span class="o">.</span><span class="n">observers</span> <span class="o">=</span> <span class="ss">:user_observer</span>
</span></code></pre></td></tr></table></div></figure>


<p>Our base app is working now, so to test it we get the url http://localhost:3000/signup in the browser.</p>

<p>Add this in app/controller/application_controller.rb:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="kp">include</span> <span class="no">AuthenticatedSystem</span>
</span></code></pre></td></tr></table></div></figure>


<p>The same line added to Application controller is removed from app/controller/sessions_controller.rb and app/controllers/users_controller.rb</p>

<p>We create a new controller for portal index</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">script</span><span class="o">/</span><span class="n">generate</span> <span class="n">controller</span> <span class="n">portal</span> <span class="n">index</span>
</span></code></pre></td></tr></table></div></figure>


<p>And modify config/routes.rb to add portal as root</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">map</span><span class="o">.</span><span class="n">root</span> <span class="ss">:controller</span> <span class="o">=&gt;</span> <span class="s2">&quot;portal&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>And last we create a layout for our application:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="x">&lt;!--app/views/layouts/application.html.erb--!&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="x">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
</span><span class='line'><span class="x">       &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="x">&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;</span>
</span><span class='line'><span class="x">&lt;head&gt;</span>
</span><span class='line'><span class="x">  &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;charset=UTF-8&quot; /&gt;</span>
</span><span class='line'><span class="x">  &lt;title&gt;Contracts: </span><span class="cp">&lt;%=</span> <span class="n">controller</span><span class="o">.</span><span class="n">action_name</span> <span class="cp">%&gt;</span><span class="x">&lt;/title&gt;</span>
</span><span class='line'><span class="x">  </span><span class="cp">&lt;%=</span> <span class="n">stylesheet_link_tag</span> <span class="s1">&#39;scaffold&#39;</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">&lt;/head&gt;</span>
</span><span class='line'><span class="x">&lt;body&gt;</span>
</span><span class='line'><span class="cp">&lt;%</span> <span class="k">if</span> <span class="n">current_user</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">   </span><span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="s1">&#39;Logout&#39;</span><span class="p">,</span> <span class="n">logout_path</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="cp">&lt;%</span> <span class="k">else</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">   </span><span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="s1">&#39;Login&#39;</span><span class="p">,</span> <span class="n">login_path</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">   </span><span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="s1">&#39;Sign up&#39;</span><span class="p">,</span> <span class="n">signup_path</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="cp">&lt;%</span> <span class="k">end</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'>
</span><span class='line'><span class="cp">&lt;%</span> <span class="o">[</span><span class="ss">:error</span><span class="p">,</span> <span class="ss">:warning</span><span class="p">,</span> <span class="ss">:notice</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">level</span><span class="o">|</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">flash</span><span class="o">[</span><span class="n">level</span><span class="o">]</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">      &lt;div class=&quot;flash </span><span class="cp">&lt;%=</span> <span class="n">level</span><span class="o">.</span><span class="n">to_s</span> <span class="cp">-%&gt;</span><span class="x">&quot;&gt;</span><span class="cp">&lt;%=</span> <span class="n">flash</span><span class="o">[</span><span class="n">level</span><span class="o">]</span> <span class="cp">-%&gt;</span><span class="x">&lt;/div&gt;</span>
</span><span class='line'><span class="x">  </span><span class="cp">&lt;%</span> <span class="k">end</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'><span class="cp">&lt;%</span> <span class="k">end</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'>
</span><span class='line'><span class="cp">&lt;%=</span> <span class="k">yield</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'>
</span><span class='line'><span class="x">&lt;/body&gt;</span>
</span><span class='line'><span class="x">&lt;/html&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Installing amqp, workling and workling_mailer</h2>

<p>Now, before using Workling, we need RabbitMQ and amqp is needed, this gem also requires EventMachine gem, so, both gems are installed when amqp is installed.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="x">gem sources -a http://gems.github.com/</span>
</span><span class='line'><span class="x">sudo gem install tmm1-amqp --no-rdoc --no-ri</span>
</span></code></pre></td></tr></table></div></figure>


<p>List your installed gems</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="x">sudo gem list</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now, install workling and workling_mailer</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="x">script/plugin install git://github.com/purzelrakete/workling.git</span>
</span><span class='line'>
</span><span class='line'><span class="x">script/plugin install git://github.com/langalex/workling_mailer.git</span>
</span></code></pre></td></tr></table></div></figure>


<p>Add this to config/environment.rb to allow workling to use RabbitMQ</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">after_initialize</span> <span class="k">do</span>
</span><span class='line'><span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">.</span><span class="n">invoker</span> <span class="o">=</span> <span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">::</span><span class="no">Invokers</span><span class="o">::</span><span class="no">EventmachineSubscriber</span>
</span><span class='line'><span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">.</span><span class="n">dispatcher</span> <span class="o">=</span> <span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">::</span><span class="no">Runners</span><span class="o">::</span><span class="no">ClientRunner</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="no">Workling</span><span class="o">::</span><span class="no">Remote</span><span class="o">.</span><span class="n">dispatcher</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="no">Workling</span><span class="o">::</span><span class="no">Clients</span><span class="o">::</span><span class="no">AmqpClient</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>To app/models/user_mailer.rb add this</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="kp">include</span> <span class="no">AsynchMail</span>
</span></code></pre></td></tr></table></div></figure>


<p>Until today I&#8217;ve seen a little issue with workling, to solve it we do the folloging in this file lib/workling/clients/memcache_queue_client.rb; verify that you have:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;memcache&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Add it if you don&#8217;t have it.</p>

<p>Amqp runs in an EventMachine cycle, so it is needed to run our app with Thin, since Thin supports EventMachine without any problem. To install Thin run</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">sudo</span> <span class="n">gem</span> <span class="n">install</span> <span class="n">thin</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">rdoc</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">ri</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Installing RabbitMQ</h2>

<p>Follow the instructions here <a href="http://jcastaneyra.com/2009/06/07/instalando-rabbitmq/">aquí</a></p>

<h2>Everybody runs</h2>

<p>Cool, naw we ensure that RabbitMQ is running.</p>

<p>Start workling client</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">script</span><span class="o">/</span><span class="n">workling_client</span> <span class="n">start</span>
</span></code></pre></td></tr></table></div></figure>


<p>And start Thin server</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">thin</span> <span class="n">start</span>
</span></code></pre></td></tr></table></div></figure>


<p>Point with your browser to http://localhost:3000 and sign up a new user, then verify your log and will see that email is sent and registered to the end of log after all operations. We can test removing include AsynchMail from UserMailer and see what happens, it would be great if you test some application with a heavy process working in the background.</p>

<p>Links:</p>

<ol>
<li><a href="http://github.com/christospappas/workling/commit/063b9849b32e0c6140a5ecdb254357770d9bd28f">http://github.com/christospappas/workling/commit/063b9849b32e0c6140a5ecdb254357770d9bd28f</a></li>
<li><a href="http://github.com/purzelrakete/workling/">http://github.com/purzelrakete/workling/</a></li>
<li><a href="http://github.com/langalex/workling_mailer/">http://github.com/langalex/workling_mailer/</a></li>
<li><a href="http://github.com/tmm1/amqp/">http://github.com/tmm1/amqp/</a></li>
<li><a href="http://github.com/technoweenie/restful-authentication/">http://github.com/technoweenie/restful-authentication/</a></li>
<li><a href="http://www.rabbitmq.com">http://www.rabbitmq.com</a></li>
<li><a href="http://code.macournoyer.com/thin/">http://code.macournoyer.com/thin/</a></li>
<li><a href="http://jcastaneyra.com/2009/06/07/instalando-rabbitmq/">Instalando RabbitMQ</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Instalando RabbitMQ]]></title>
    <link href="http://jcastaneyra.com/2009/06/07/instalando-rabbitmq/"/>
    <updated>2009-06-07T00:00:00-05:00</updated>
    <id>http://jcastaneyra.com/2009/06/07/instalando-rabbitmq</id>
    <content type="html"><![CDATA[<p><a name="rabbitmq_spanish"/><strong>Instalando RabbitMQ</strong></a> (<a href="#rabbitmq_english">English</a>)</p>

<p>RabbitMQ es un sistema de message queue (MQ), el cual provee comunicaciones asíncronas, es decir que el productor y consumidor no tienen la necesidad de interactuar con los mensajes al mismo tiempo, además de que es una implementación del protocolo AMQP (Advanced Message Queuing Protocol), un protocolo para mensajeo de alto rendimiento, y por último decir que RabbitMQ está desarrollado con Erlang, Erlang es un lenguaje de programación funcional.</p>

<!-- more -->


<h2>En Ubuntu 9.04</h2>

<p>La instalación de RabbitMQ en Ubuntu 9.04 es tan simple como correr el comando</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo aptitude install rabbitmq-server</span></code></pre></td></tr></table></div></figure>


<p>Y con el cual si no has instalado Erlang te mostrará que paquetes tendrá que instalar para que lo tengas también.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>jcastaneyra@ubuntu:~/sources$ sudo aptitude install rabbitmq-server
</span><span class='line'>[sudo] password for jcastaneyra:
</span><span class='line'>Reading package lists... Done
</span><span class='line'>Building dependency tree
</span><span class='line'>Reading state information... Done
</span><span class='line'>Reading extended state information
</span><span class='line'>Initializing package states... Done
</span><span class='line'>Writing extended state information... Done
</span><span class='line'>The following NEW packages will be installed:
</span><span class='line'>erlang-base{a} erlang-nox{a} libltdl7{a} odbcinst1debian1{a} unixodbc{a}
</span><span class='line'>The following partially installed packages will be configured:
</span><span class='line'>rabbitmq-server
</span><span class='line'>0 packages upgraded, 5 newly installed, 0 to remove and 8 not upgraded.
</span><span class='line'>Need to get 28.6MB of archives. After unpacking 46.9MB will be used.
</span><span class='line'>Do you want to continue? [Y/n/?]</span></code></pre></td></tr></table></div></figure>


<p>Una vez instalado ya está corriendo.</p>

<h2>En Mac leopard</h2>

<p><em>UPDATE (27/05/2010)</em>: Desde hace un rato que ya estoy usando Homebrew para instalar cosas en Mac, ya existe una fórmula para instalar también RabbitMQ  y por supuesto Erlang, para más información visitar <a href="http://github.com/mxcl/homebrew">http://github.com/mxcl/homebrew</a> y seguir las instrucciones para instalar Homebrew. Con RabbitMQ, incluso si se quiere una versión específica de RabbitMQ se puede modificar la fórmula :)</p>

<p>La instalación es a través de los MacPorts, hay que bajar el instalador de la página www.macports.org/install.php, pero para poder compilar es necesario tener XCode instalado. Los MacPorts son instalados en /opt, por lo que hay que asegurarnos que se tengamos agregados los paths necesarios en el profile para ejecutar los comandos de MacPorts.</p>

<p>En mi caso en .profile (pero también puede ser el .bash_login) debe estar algo así (si no está lo agrego):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># MacPorts Installer addition on 2009-02-25_at_15:37:48: adding an appropriate PATH variable for use with MacPorts.
</span><span class='line'>export PATH=/opt/local/bin:/opt/local/sbin:$PATH
</span><span class='line'># Finished adapting your PATH environment variable for use with MacPorts.
</span><span class='line'>
</span><span class='line'># MacPorts Installer addition on 2009-02-25_at_15:37:48: adding an appropriate MANPATH variable for use with MacPorts.
</span><span class='line'>export MANPATH=/opt/local/share/man:$MANPATH
</span><span class='line'># Finished adapting your MANPATH environment variable for use with MacPorts.</span></code></pre></td></tr></table></div></figure>


<p>Una vez que están los MacPorts hay que instalar primero erlang, así que ejecutamos</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo port install erlang</span></code></pre></td></tr></table></div></figure>


<p>Y esperamos un buen rato a que se instale.</p>

<p>Una vez instalado erlang, bajamos la última versión de RabbitMQ</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>mkdir /tmp/rabbitmq && cd /tmp/rabbitmq
</span><span class='line'>curl -O http://www.rabbitmq.com/releases/rabbitmq-server/v1.5.5/rabbitmq-server-generic-unix-1.5.5.tar.gz
</span><span class='line'>tar xvzf rabbitmq-server-generic-unix-1.5.5.tar.gz
</span><span class='line'>sudo mv rabbitmq_server-1.5.5/ /opt/local/lib/erlang/lib</span></code></pre></td></tr></table></div></figure>


<p>Ahora ya lo podemos ejecutar.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo /opt/local/lib/erlang/lib/rabbitmq_server-1.5.5/sbin/rabbitmq-server</span></code></pre></td></tr></table></div></figure>


<h2>Recursos</h2>

<ol>
<li><a href="http://www.rabbitmq.com">http://www.rabbitmq.com</a></li>
<li><a href="http://playtype.net/past/2008/10/9/installing_rabbitmq_on_osx/">http://playtype.net/past/2008/10/9/installing_rabbitmq_on_osx/</a></li>
</ol>


<p><a name="rabbitmq_english"/><strong>Installing RabbitMQ</strong></a> (<a href="#rabbitmq_spanish">Español</a>)</p>

<p>RabbitMQ is a complete and highly reliable Enterprise Messaging system, it provides asynchronous communications,  meaning that the sender and receiver of the message do not need to interact with the message queue at the same time, also it is a AMQP implementation (Advanced Message Queuing Protocol) a protocol for high performance messaging, and last RabbitMQ is developed with Erlang, a functional programming language.</p>

<h2>In Ubuntu 9.04</h2>

<p>RabbitMQ instalation in Ubuntu 9.04 is so simple, it is just needed to run a command</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo aptitude install rabbitmq-server</span></code></pre></td></tr></table></div></figure>


<p>With this also install all packages needed by rabbitmq, Erlang is installed also.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>jcastaneyra@ubuntu:~/sources$ sudo aptitude install rabbitmq-server
</span><span class='line'>[sudo] password for jcastaneyra:
</span><span class='line'>Reading package lists... Done
</span><span class='line'>Building dependency tree
</span><span class='line'>Reading state information... Done
</span><span class='line'>Reading extended state information
</span><span class='line'>Initializing package states... Done
</span><span class='line'>Writing extended state information... Done
</span><span class='line'>The following NEW packages will be installed:
</span><span class='line'>erlang-base{a} erlang-nox{a} libltdl7{a} odbcinst1debian1{a} unixodbc{a}
</span><span class='line'>The following partially installed packages will be configured:
</span><span class='line'>rabbitmq-server
</span><span class='line'>0 packages upgraded, 5 newly installed, 0 to remove and 8 not upgraded.
</span><span class='line'>Need to get 28.6MB of archives. After unpacking 46.9MB will be used.
</span><span class='line'>Do you want to continue? [Y/n/?]</span></code></pre></td></tr></table></div></figure>


<p>Once the installation is finished RabbitMQ will be running.</p>

<h2>In Mac leopard</h2>

<p><em>UPDATE (27/05/2010)</em>: I am using Homebrew to install some stuff in Mac from some months ago, Homebrew has a formula to install RabbitMQ and also Erlang, for more info please visit <a href="http://github.com/mxcl/homebrew">http://github.com/mxcl/homebrew</a> for install instructions. Also if you want to install a different version of RabbitMQ you can do it just editing the formula :)</p>

<p>RabbitMQ installation is done through MacPorts, you need to download the MacPorts installer from www.macports.org/install.php, also XCode is needed. MacPorts are installed in /opt, for that reason we put these paths in the .profile file (could be .bash_login), if you don&#8217;t have these paths add them to your profile file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># MacPorts Installer addition on 2009-02-25_at_15:37:48: adding an appropriate PATH variable for use with MacPorts.
</span><span class='line'>export PATH=/opt/local/bin:/opt/local/sbin:$PATH
</span><span class='line'># Finished adapting your PATH environment variable for use with MacPorts.
</span><span class='line'>
</span><span class='line'># MacPorts Installer addition on 2009-02-25_at_15:37:48: adding an appropriate MANPATH variable for use with MacPorts.
</span><span class='line'>export MANPATH=/opt/local/share/man:$MANPATH
</span><span class='line'># Finished adapting your MANPATH environment variable for use with MacPorts.</span></code></pre></td></tr></table></div></figure>


<p>In order to install erlang execute the following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo port install erlang</span></code></pre></td></tr></table></div></figure>


<p>You need to wait some time, maybe several minutes :)</p>

<p>Once you have erlang installed, we download the last RabbitMQ version</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>mkdir /tmp/rabbitmq && cd /tmp/rabbitmq
</span><span class='line'>curl -O http://www.rabbitmq.com/releases/rabbitmq-server/v1.5.5/rabbitmq-server-generic-unix-1.5.5.tar.gz
</span><span class='line'>tar xvzf rabbitmq-server-generic-unix-1.5.5.tar.gz
</span><span class='line'>sudo mv rabbitmq_server-1.5.5/ /opt/local/lib/erlang/lib</span></code></pre></td></tr></table></div></figure>


<p>Now we execute rabbitmq-server with this</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo /opt/local/lib/erlang/lib/rabbitmq_server-1.5.5/sbin/rabbitmq-server</span></code></pre></td></tr></table></div></figure>


<h2>Links</h2>

<ol>
<li><a href="http://www.rabbitmq.com">http://www.rabbitmq.com</a></li>
<li><a href="http://playtype.net/past/2008/10/9/installing_rabbitmq_on_osx/">http://playtype.net/past/2008/10/9/installing_rabbitmq_on_osx/</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mostrando el branch de git en el prompt de la consola]]></title>
    <link href="http://jcastaneyra.com/2009/05/20/mostrando-el-branch-de-git-en-el-prompt-de-la-consola/"/>
    <updated>2009-05-20T00:00:00-05:00</updated>
    <id>http://jcastaneyra.com/2009/05/20/mostrando-el-branch-de-git-en-el-prompt-de-la-consola</id>
    <content type="html"><![CDATA[<p><strong>Mostrando el branch de git en el prompt de la consola</strong> (In english below)</p>

<p>Tiene aproximadamente dos meses que empecé a trabajar con git, y la experiencia ha sido muy buena, bastante interesante, pero con los primeros tutoriales que empecé a ver noté que los aliases ayudan a hacer más ágil el trabajo con git, curiosamente hasta este momento no los he usado, creo que ha llegado la hora de agregarlos en mi configuración. Así que al final de mi archivo $HOME/.gitconfig agrego:</p>

<pre><code>[color]
        ui = auto
[alias]
        ci = commit
        co = checkout
        st = status
</code></pre>

<!-- more -->


<p>Por cierto, que la parte de [color] es para mostrar con colores mis cambios cuando le doy git status, aunque ahora con estos cambios ya le podría dar git st.&lt;/p&gt; &lt;p&gt;Otra cosa que noté en mis inicios con git fue que en un screencast de peepcode, en el prompt de la consola aparecía el branch en el que se encontraba trabajando, en ese entonces busqué como hacerlo pero no tuve éxito hasta ahora, entonces para lograr esto hay que agregar un archivo con funciones .bash_functions</p>

<pre><code># git-related functions in here

git_branch () {
  GIT_BRANCH="$(git branch --no-color 2&gt; /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')"
  if [[ -n "$GIT_BRANCH" ]] ; then
    echo ":($GIT_BRANCH) "
  fi
}
empty_branch () {
  name="$1"
  if [[ -n "$name" ]] ; then
    echo "This will create a new empty branch in the current"
    echo -n "git repository called '${name}' ... Continue? [y/N] "
    read VERIFY
    if [[ "$VERIFY" = "Y" || "$VERIFY" = "y" ]]; then
      echo "creating branch '$name'"
      git symbolic-ref HEAD refs/heads/$name
      rm .git/index
      git clean -fdx
      echo "you should be on your new empty branch! "
      echo "add/commit files as usual! "
      echo "( your new branch will show up after you commit something to it )"
    else
      echo -n ""
    fi
  else
    echo "Creates a new empty branch in your git repository."
    echo ""
    echo "Usage: empty_branch [name_of_new_branch]"
  fi
}

# vim:set ft=sh:
</code></pre>

<p>Y dependiendo del archivo de configuración del shell que estén usando agregar en él esto:</p>

<pre><code># if .bash_functions if a file then source it
# if .bash_functions is a directory, then sourec all its files
if [ -f ~/.bash_functions ]; then
  . ~/.bash_functions
fi
if [ -d ~/.bash_functions ]; then
  for function in ~/.bash_functions/*; do . $function; done
fi

# bash prompt
prompt () {
  PS1="\[\e[34m\]\u\[\e[37m\]@\[\e[36m\]\h\[\e[37m\]:\[\e[31m\]\w\[\e[37m\]$(git_branch)$ "
}
PROMPT_COMMAND=prompt
export PROMPT_COMMAND
</code></pre>

<p>En mi caso, en leopard yo estoy usando .profile, pero podría ser .bash_rc o algún otro profile de shell. Ya para cargar la info del profile habría que ejecutar source .profile ó bien salirse de la consola y volverla a abrir para que cargue la nueva configuración.</p>

<p>Todavía falta mucho por aprender de git, pero creo que voy por buen camino, también he aprendido bastante de los flujos que siguen algunos equipos de trabajo ágiles, son muy interesantes.</p>

<h2>Recursos:</h2>

<ol>
<li><a href="http://git.or.cz/gitwiki/Aliases">Aliases</a></li>
<li><a href="http://github.com/remi/home/blob/9520493b8c2a2c3f290d64a33df13e0763aac50c/.bash_functions/git">.bash_functions file from Remi</a></li>
<li><a href="http://github.com/remi/home/blob/9520493b8c2a2c3f290d64a33df13e0763aac50c/.bashrc">.bash_rc file from Remi</a></li>
<li><a href="http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html">Git workflow for agile teams</a></li>
</ol>


<p><strong>Showing the git branch in the console prompt</strong></p>

<p>I have working with git since started two months ago, the experience have been too good, I must say awesome, when I started to work I saw that you could use aliases with git, it is funny but since then I&#8217;ve never used aliases, so now it&#8217;s time to add them to my configuration file $HOME/.gitconfig</p>

<pre><code>[color]
        ui = auto
[alias]
        ci = commit
        co = checkout
        st = status
</code></pre>

<p>This [color] section enable colors when I execute git status and see my changes, but now with my aliases I could write git st.&lt;/p&gt; &lt;p&gt;Another nice stuff that I noticed when started to work with git and I was watching a Peepcode screencast was that in the console prompt appeared the git branch, in that moment I googled it but no results got, until now that I found how to do this; one file with the git functions is created .bash_functions</p>

<pre><code># git-related functions in here

git_branch () {
  GIT_BRANCH="$(git branch --no-color 2&gt; /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')"
  if [[ -n "$GIT_BRANCH" ]] ; then
    echo ":($GIT_BRANCH) "
  fi
}
empty_branch () {
  name="$1"
  if [[ -n "$name" ]] ; then
    echo "This will create a new empty branch in the current"
    echo -n "git repository called '${name}' ... Continue? [y/N] "
    read VERIFY
    if [[ "$VERIFY" = "Y" || "$VERIFY" = "y" ]]; then
      echo "creating branch '$name'"
      git symbolic-ref HEAD refs/heads/$name
      rm .git/index
      git clean -fdx
      echo "you should be on your new empty branch! "
      echo "add/commit files as usual! "
      echo "( your new branch will show up after you commit something to it )"
    else
      echo -n ""
    fi
  else
    echo "Creates a new empty branch in your git repository."
    echo ""
    echo "Usage: empty_branch [name_of_new_branch]"
  fi
}

# vim:set ft=sh:
</code></pre>

<p>And depending which shell are you using you add this into it</p>

<pre><code># if .bash_functions if a file then source it
# if .bash_functions is a directory, then sourec all its files
if [ -f ~/.bash_functions ]; then
  . ~/.bash_functions
fi
if [ -d ~/.bash_functions ]; then
  for function in ~/.bash_functions/*; do . $function; done
fi

# bash prompt
prompt () {
  PS1="\[\e[34m\]\u\[\e[37m\]@\[\e[36m\]\h\[\e[37m\]:\[\e[31m\]\w\[\e[37m\]$(git_branch)$ "
}
PROMPT_COMMAND=prompt
export PROMPT_COMMAND
</code></pre>

<p>I&#8217;m using .profile in leopard, but could be .bash_rc. Now to load this new changes from your profile it&#8217;s need to execute source .profile or you also could close your console window and open a new one.</p>

<p>I&#8217;ve learned a lot until now but I still need to learn more (even english :) ), I&#8217;ve learned also from agile workflows that helps with your work.</p>

<h2>Notes:</h2>

<ol>
<li><a href="http://git.or.cz/gitwiki/Aliases">Aliases</a></li>
<li><a href="http://github.com/remi/home/blob/9520493b8c2a2c3f290d64a33df13e0763aac50c/.bash_functions/git">.bash_functions file from Remi</a></li>
<li><a href="http://github.com/remi/home/blob/9520493b8c2a2c3f290d64a33df13e0763aac50c/.bashrc">.bash_rc file from Remi</a></li>
<li><a href="http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html">Git workflow for agile teams</a></li>
</ol>


<p>Another note:</p>

<p>This is my first try to write in english, I definitely need to learn to be more fluid in my english writing also speaking, but it&#8217;s needed to start in some place. So if this is not understandable you can give some feedback, thanks.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Segunda reunión de MXOR]]></title>
    <link href="http://jcastaneyra.com/2009/03/17/segunda-reunion-de-mxor/"/>
    <updated>2009-03-17T00:00:00-06:00</updated>
    <id>http://jcastaneyra.com/2009/03/17/segunda-reunion-de-mxor</id>
    <content type="html"><![CDATA[<p>El día de ayer fue la segunda reunión de nuestro grupo de Rails MXOR, en el cuál se hablaron de diversos tópicos en general, pero como todos estamos interesados en aprender de estos tópicos llegamos a la idea de trabajar en un proyecto en donde se pueda trabajar con las cosas que nos interesan y que de esto surgan una serie de artículos los cuales puedan servirnos a nosotros como referencia y a las personas interesadas en Rails y de todo lo que está al rededor.</p>

<!-- more -->


<p>Sobre los tópicos que nos resultaron interesantes son:</p>

<ul>
<li>Instalación de Linux desde cero y con los necesario para Rails</li>
<li>Version de Rails, VM&#8217;s</li>
<li>Uso de Git con el proyecto</li>
<li>RedMine como administrador de proyecto</li>
<li>BDD</li>
<li>Autenticación</li>
<li>Servidores Web, App Servers</li>
<li>Prototype, scriptaculous, JQuery (Edgar dice que es más ligero)</li>
<li>CSS (blueprint, haml)</li>
<li>Deployment</li>
<li>Cache</li>
<li>Plugins de consulta</li>
<li>I18N</li>
</ul>


<p>En la reunión se hizo una lluvia de ideas sobre que proyectos trabajar y sobre el proyecto que se eligió también se fueron aterrizando diversas ideas.</p>

<h2>Problema:</h2>

<p>Compartir historias de desarrolladores.</p>

<h2>El contenido:</h2>

<p>Tutoriales
Errores
Categorización de tutoriales
Categorización de Errores
Como wiki de errores
¿Compartir pasos de recetas?
Solo en español para empezar</p>

<p>Hasta aquí me quedé en las anotaciones ya que tuve que salir temprano, pero hay un podcast con la sesión de principio a fin. En este momento se está seleccionando un nombre para la aplicación, una vez que se haya elegido el nombre se podrá empezar a trabajar en estos tópicos, idealmente la gente involucrada en cada actividad sería la que esté interesada en aprender y no precisamente la que domine el tema. La lista de nombres al momento es:</p>

<ul>
<li>redcipe (3 votos)</li>
<li>errecipe (1 voto)</li>
<li>devrecipes (0 votos)</li>
<li>devcipe (1 voto)</li>
</ul>


<p>Por supuesto este es un proyecto open source y abierto a la comunidad interesada en Rails, buscando que a partir de esto surgan artículos e información que en un momento dado nos sea de utilidad, una especie de libro que nos sirva de guía en la realización de una aplicación. Para más información acudir a la <a href="http://mexicoonrails.com.mx/news/12">página del grupo</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Scaling Rails]]></title>
    <link href="http://jcastaneyra.com/2009/02/27/scaling-rails/"/>
    <updated>2009-02-27T00:00:00-06:00</updated>
    <id>http://jcastaneyra.com/2009/02/27/scaling-rails</id>
    <content type="html"><![CDATA[<p>Hace un par de semanas aproximadamente buscando información de como hacer escalar aplicaciones Rails me encontré con un material bastante interesante y con información muy valiosa, y lo mejor de todo es que en screencasts, los cuales han sido publicados por Gregg Pollack de <a href="http://railsenvy.com">RailsEnvy</a> con el soporte de <a href="http://newrelic.com/">NewRelic</a>, sería muy bueno que les den una revisada. Los screencasts publicados hasta el momento son:</p>

<ol>
    <li><a href="http://railslab.newrelic.com/2009/01/22/introduction">Introduction</a></li>
    <li><a href="http://railslab.newrelic.com/2009/01/22/page-responsiveness">Page Responsiveness</a></li>
    <li><a href="http://railslab.newrelic.com/2009/01/22/page-caching">Page Caching</a></li>
    <li><a href="http://railslab.newrelic.com/2009/01/22/cache-expiration">Chache Expiration</a></li>
    <li><a href="http://railslab.newrelic.com/2009/01/22/new-relic-rpm">New Relic RPM</a></li>
    <li><a href="http://railslab.newrelic.com/2009/02/05/episode-5-advanced-page-caching">Advanced Page Caching</a></li>
    <li><a href="http://railslab.newrelic.com/2009/02/09/episode-6-action-caching">Action Caching</a></li>
    <li><a href="http://railslab.newrelic.com/2009/02/09/episode-7-fragment-caching">Fragment Caching</a></li>
    <li><a href="http://railslab.newrelic.com/2009/02/19/episode-8-memcached">Memcahed</a></li>
    <li><a href="http://railslab.newrelic.com/2009/02/19/episode-9-taylor-weibley-databases">Taylor Weibley &amp; Databases</a></li>
    <li><a href="http://railslab.newrelic.com/2009/02/25/episode-10-client-side-caching">Client-side Caching</a></li>
    <li><a href="http://railslab.newrelic.com/2009/02/26/episode-11-advanced-http-caching">Additional HTTP Caching</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mi participación en el BarCamp 2 México]]></title>
    <link href="http://jcastaneyra.com/2009/02/10/mi-participacion-en-el-barcamp-2-mexico/"/>
    <updated>2009-02-10T00:00:00-06:00</updated>
    <id>http://jcastaneyra.com/2009/02/10/mi-participacion-en-el-barcamp-2-mexico</id>
    <content type="html"><![CDATA[<p>Así es, el pasado sábado hice presencia en el BarCamp 2 México con mi comunidad de <a href="http://mexicoonrails.com.mx/">México on Rails</a> y aporté mi granito de arena con una presentación sobre como instalar Rails en Windows la cuál fue enriquecida por mis compañeros de la comunidad, cómo comunidad y equipo llevamos varias presentaciones al BarCamp, las cuáles se estarán subiendo a nuestro sitio de México On Rails, también les dejo dos reseñas, <a href="http://mexicoonrails.com.mx/news/7">una por nuestro compañero de la comunidad @chubas</a> donde da un resumen de todas las ponencias que dimos como grupo y la <a href="http://www.tequilavalley.com/2009/02/09/fuimos-mas-de-140-creo-barcamp-mexico-2/">otra por @tequilavalley</a>.</p>

<p>La presentación la dejo aquí:</p>

<div id="__ss_1012895" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="Instalando Rails en Windows" href="http://www.slideshare.net/jcastaneyra/instalando-rails-en-windows?type=presentation">Instalando Rails en Windows</a><object width="425" height="355" data="http://static.slideshare.net/swf/ssplayer2.swf?doc=mxorrorwindows-1234286003510859-3&amp;stripped_title=instalando-rails-en-windows" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=mxorrorwindows-1234286003510859-3&amp;stripped_title=instalando-rails-en-windows" /><param name="allowfullscreen" value="true" /></object>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/jcastaneyra">jcastaneyra</a>. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/ruby">ruby</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/on">on</a>)</div>
</div>

]]></content>
  </entry>
  
</feed>
