Installing RabbitMQ + Stomp in Ubuntu/Mac

En español

In the project I’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.

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

  • RabbitMQ 1.6.0 installed, here there are some steps to install it.
  • Mercurial is needed to download Stomp code
  • Download Stomp code
  • hg clone -r rabbitmq_v1_6_0 http://hg.rabbitmq.com/rabbitmq-stomp
    
  • 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)
  • cd rabbitmq-stomp
    make RABBIT_SERVER_INCLUDE_DIR=/usr/lib/erlang/lib/rabbitmq_server-1.6.0/include
    
  • Copy your compiled Stomp to the Erlang libraries
  • sudo mkdir -p /usr/lib/erlang/lib/rabbitmq-stomp
    sudo cp -R * /usr/lib/erlang/lib/rabbitmq-stomp
    
  • 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)
sudo vim /etc/rabbitmq/rabbitmq.conf
#Add the lines below
NODENAME=rabbit
NODE_IP_ADDRESS=0.0.0.0
NODE_PORT=5672

LOG_BASE=/var/log/rabbitmq
MNESIA_BASE=/var/lib/rabbitmq/mnesia

SERVER_START_ARGS='
  -pa /usr/lib/erlang/lib/rabbitmq-stomp/ebin
  -rabbit
    stomp_listeners [{"0.0.0.0",61613}]
    extra_startup_steps [{"STOMP-listeners",rabbit_stomp,kickstart,[]}]'

And that’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)

deploy@localhost:~$ sudo rabbitmq-server
RabbitMQ 1.6.0 (AMQP 8-0)
Copyright (C) 2007-2009 LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd.
Licensed under the MPL.  See http://www.rabbitmq.com/

node        : rabbit@localhost
log         : /var/log/rabbitmq/rabbit.log
sasl log    : /var/log/rabbitmq/rabbit-sasl.log
database dir: /var/lib/rabbitmq/mnesia/rabbit

starting database             ...done
starting core processes       ...done
starting recovery             ...done
starting persister            ...done
starting guid generator       ...done
starting builtin applications ...done
starting TCP listeners        ...done
starting STOMP-listeners      ...done

broker running

In english

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.

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.

  • Tener instalado RabbitMQ 1.6.0, aquí hay unos pasos para instalarlo.
  • Tener instalado Mercurial para bajar el código de Stomp
  • Bajar el código de Stomp
  • hg clone -r rabbitmq_v1_6_0 http://hg.rabbitmq.com/rabbitmq-stomp
    
  • 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)
  • cd rabbitmq-stomp
    make RABBIT_SERVER_INCLUDE_DIR=/usr/lib/erlang/lib/rabbitmq_server-1.6.0/include
    
  • Copiar Stomp compilado al directorio de librerías de Erlang
  • sudo mkdir -p /usr/lib/erlang/lib/rabbitmq-stomp
    sudo cp -R * /usr/lib/erlang/lib/rabbitmq-stomp
    
  • 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)
sudo vim /etc/rabbitmq/rabbitmq.conf
#Add the lines below
NODENAME=rabbit
NODE_IP_ADDRESS=0.0.0.0
NODE_PORT=5672

LOG_BASE=/var/log/rabbitmq
MNESIA_BASE=/var/lib/rabbitmq/mnesia

SERVER_START_ARGS='
  -pa /usr/lib/erlang/lib/rabbitmq-stomp/ebin
  -rabbit
    stomp_listeners [{"0.0.0.0",61613}]
    extra_startup_steps [{"STOMP-listeners",rabbit_stomp,kickstart,[]}]'

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)

deploy@localhost:~$ sudo rabbitmq-server
RabbitMQ 1.6.0 (AMQP 8-0)
Copyright (C) 2007-2009 LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd.
Licensed under the MPL.  See http://www.rabbitmq.com/

node        : rabbit@localhost
log         : /var/log/rabbitmq/rabbit.log
sasl log    : /var/log/rabbitmq/rabbit-sasl.log
database dir: /var/lib/rabbitmq/mnesia/rabbit

starting database             ...done
starting core processes       ...done
starting recovery             ...done
starting persister            ...done
starting guid generator       ...done
starting builtin applications ...done
starting TCP listeners        ...done
starting STOMP-listeners      ...done

broker running

, , , , ,

View Comments

Bundler gem and Daemons error (The default Gemfile was not found)

(En español)

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.

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

/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)
	from /usr/lib/ruby/gems/1.8/gems/bundler-0.9.3/lib/bundler.rb:64:in `setup'

So, looking for this error in google we didn’t get anything, and looking into the bundler gem code the solution to this problems was:

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

The complete daemon code here:

(In english)

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.

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

/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)
	from /usr/lib/ruby/gems/1.8/gems/bundler-0.9.3/lib/bundler.rb:64:in `setup'

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.

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

El código completo del demonio es el siguiente:

, , ,

View Comments

Se busca desarrollador rails

Descripción
Se solicita desarrollador Rails para mantener una aplicación web que está a punto de salir en su versión beta. Tendrá que resolver issues y bugs durante la versión beta, posteriormente será muy probable que tenga que implementar nuevos requerimientos.
Conocimiento técnico
- Lenguaje de programación Ruby
- Conocimientos del framework Ruby On Rails
- Conocer MySQL
- Conocimientos básicos de web services REST
- Javascript y jQuery
- HTML, CSS
- Conocimiento de Linux
- Conocer Git
- Conocimientos básicos de objective c (deseable)
Requerimientos
- 1+ años de experiencia
- Que sea proactivo y muestre interés y pasión por las nuevas tecnologías
- Responsable
- Vivir en el Distrito Federal, México

Nota: Deja un comentario aquí si estás interesado o bien manda un correo con tu CV a jcastaneyra@gmail.com.

,

View Comments

Table names case insensitive for MySQL Linux

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.

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.

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:

lower_case_table_names=1

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.

View Comments

Como crear un archivo zip con ruby

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!!!

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

Espero que les sirva como a mi.

Links:

http://ruby-doc.org/core/classes/Dir.html
http://ruby-doc.org/core/classes/FileUtils.html
http://rubyzip.sourceforge.net/

View Comments

Etiquetando código en git/Tagging code in git

Etiquetando código en git (English)

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.

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:

git tag -a -m "My old and ugly style" old_style

Para ver nuestros tags locales tenemos que ejecutar

git tag -l

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

git tag -l -n1

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

git push origin --tags

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:

git checkout -f -b mybranch old_style

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

Links:

http://ariejan.net/2009/09/05/git-tag-mini-cheat-sheet-revisited/?doing_wp_cron
http://polywww.in2p3.fr/~gaycken/Calice/Software/my_git_workflow.html

Tagging code in git (Español)

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.

I’m not a git expert, but this worked for me. First of all, we need to tag our code, use this command:

git tag -a -m "My old and ugly style" old_style

In order to see all local tags

git tag -l

Since I added a description to my tag it’s needed to execute the following to see the description

git tag -l -n1

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

git push origin --tags

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:

git checkout -f -b mybranch old_style

With this command you would have a new branch with the code tagged with old_style.

Links:

http://ariejan.net/2009/09/05/git-tag-mini-cheat-sheet-revisited/?doing_wp_cron
http://polywww.in2p3.fr/~gaycken/Calice/Software/my_git_workflow.html

View Comments

Enviando correo de manera asíncrona en Rails usando Workling, Workling-Mailer y RabbitMQ

Enviando correo de manera asíncrona en Rails usando Workling, Workling-Mailer y RabbitMQ (English)

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’s, etc.

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.

Aplicación base

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

Lo primero que hacemos es crear la aplicación en rails

rails mail_async_example -d mysql
 
rm public/index.html
 
script/plugin install git://github.com/technoweenie/restful-authentication.git
 
script/generate authenticated user sessions --include-activation

Creamos nuestra base de datos y migramos

rake db:create
 
rake db:migrate

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:

config/routes.rb

map.activate 'activate/:activation_code', :controller => 'users', :action => 'activate', :activation_code => nil

config/environment.rb

config.active_record.observers = :user_observer

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

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

include AuthenticatedSystem

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

Y creamos un nuevo controlador

script/generate controller portal index

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

map.root :controller => "portal"

Por último agregamos un layout para nuestra aplicación:

app/views/layouts/application.html.erb

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Contracts: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>
<% if current_user %>
   <%= link_to 'Logout', logout_path %>
<% else %>
   <%= link_to 'Login', login_path %>
   <%= link_to 'Sign up', signup_path %>
<% end %>
 
<% [:error, :warning, :notice].each do |level|
    if flash[level] -%>
      <div class="flash <%= level.to_s -%>"><%= flash[level] -%></div>
  <% end -%>
<% end -%>
 
<%= yield %>
 
</body>
</html>

Instalando amqp, workling y workling_mailer

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.

gem sources -a http://gems.github.com/
sudo gem install tmm1-amqp --no-rdoc --no-ri

Vemos nuestro listado de gemas

sudo gem list

Ahora si, a instalar workling y workling_mailer

script/plugin install git://github.com/purzelrakete/workling.git
 
script/plugin install git://github.com/langalex/workling_mailer.git

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

config.after_initialize do
Workling::Remote.invoker = Workling::Remote::Invokers::EventmachineSubscriber
Workling::Remote.dispatcher = Workling::Remote::Runners::ClientRunner.new
Workling::Remote.dispatcher.client = Workling::Clients::AmqpClient.new
end

Posteriormente en app/models/user_mailer.rb añadimos

include AsynchMail

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:

require 'memcache'

Al principio del archivo, si no lo tienes agrégalo.

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

sudo gem install thin --no-rdoc --no-ri

Instalando RabbitMQ

Checar la instalación aquí http://www.jcastaneyra.com/2009/06/07/instalando-rabbitmq/

A correr todos

Nos aseguramos de que el RabbitMQ esté corriendo.

Iniciamos el cliente de workling

script/workling_client start

E iniciamos el servidor thin

thin start

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.

Referencias:

http://github.com/christospappas/workling/commit/063b9849b32e0c6140a5ecdb254357770d9bd28f
http://github.com/purzelrakete/workling/
http://github.com/langalex/workling_mailer/
http://github.com/tmm1/amqp/
http://github.com/technoweenie/restful-authentication/
http://www.rabbitmq.com
http://code.macournoyer.com/thin/
http://www.jcastaneyra.com/2009/06/07/instalando-rabbitmq/

Sending mails in asynchronous way in Rails using Workling, Workling-Mailer and RabbitMQ (Español)

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.

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.

Base application

We create a simple application with restful_authentication and activation option.

First of all we create the rails app

rails mail_async_example -d mysql
 
rm public/index.html
 
script/plugin install git://github.com/technoweenie/restful-authentication.git
 
script/generate authenticated user sessions --include-activation

Now with rake we create and migrate DB

rake db:create
 
rake db:migrate

Following the restful_authentication instructions to send mail we add this:

config/routes.rb

map.activate 'activate/:activation_code', :controller => 'users', :action => 'activate', :activation_code => nil

config/environment.rb

config.active_record.observers = :user_observer

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

Add this in app/controller/application_controller.rb:

include AuthenticatedSystem

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

We create a new controller for portal index

script/generate controller portal index

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

map.root :controller => "portal"

And last we create a layout for our application:

app/views/layouts/application.html.erb

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Contracts: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>
<% if current_user %>
   <%= link_to 'Logout', logout_path %>
<% else %>
   <%= link_to 'Login', login_path %>
   <%= link_to 'Sign up', signup_path %>
<% end %>
 
<% [:error, :warning, :notice].each do |level|
    if flash[level] -%>
      <div class="flash <%= level.to_s -%>"><%= flash[level] -%></div>
  <% end -%>
<% end -%>
 
<%= yield %>
 
</body>
</html>

Installing amqp, workling and workling_mailer

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.

gem sources -a http://gems.github.com/
sudo gem install tmm1-amqp --no-rdoc --no-ri

List your installed gems

sudo gem list

Now, install workling and workling_mailer

script/plugin install git://github.com/purzelrakete/workling.git
 
script/plugin install git://github.com/langalex/workling_mailer.git

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

config.after_initialize do
Workling::Remote.invoker = Workling::Remote::Invokers::EventmachineSubscriber
Workling::Remote.dispatcher = Workling::Remote::Runners::ClientRunner.new
Workling::Remote.dispatcher.client = Workling::Clients::AmqpClient.new
end

To app/models/user_mailer.rb add this

include AsynchMail

Until today I’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:

require 'memcache'

Add it if you don’t have it.

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

sudo gem install thin --no-rdoc --no-ri

Installing RabbitMQ

Follow the instructions here http://www.jcastaneyra.com/2009/06/07/instalando-rabbitmq/

Everybody runs

Cool, naw we ensure that RabbitMQ is running.

Start workling client

script/workling_client start

And start Thin server

thin start

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.

Links:

http://github.com/christospappas/workling/commit/063b9849b32e0c6140a5ecdb254357770d9bd28f
http://github.com/purzelrakete/workling/
http://github.com/langalex/workling_mailer/
http://github.com/tmm1/amqp/
http://github.com/technoweenie/restful-authentication/
http://www.rabbitmq.com
http://code.macournoyer.com/thin/
http://www.jcastaneyra.com/2009/06/07/instalando-rabbitmq/

, , , , , ,

View Comments