Posts tagged Ruby

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:

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/

Mi participación en el BarCamp 2 México

Así es, el pasado sábado hice presencia en el BarCamp 2 México con mi comunidad de México on Rails 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, una por nuestro compañero de la comunidad @chubas donde da un resumen de todas las ponencias que dimos como grupo y la otra por @tequilavalley.

La presentación la dejo aquí:

Libros nuevos II

Un poquito antes de que el inche dolar se fuera arriba de los $13 pesos me compré unos libros en EU, de esos que compras en línea (Amazon, Pragmatic Books). Estos libros recien adquiridos son “Pragmatic Thinking & Learning” (Andy Hunt) y “Programming Ruby 1.9″ (Dave Thomas, Chad Fowler y Andy Hunt), estos dos de Pragmatic Programmers books.

El libro de Ruby 1.9 es más que obvio de que nos habla, del lenguaje Ruby por supuesto, y también obvio es para qué lo quiero, para levantar una de las patas de la cama :) , y para mejorar también mis skills en este lenguaje, aquí el detalle va a ser como me voy a organizar para leerlo, terminarlo, comprenderlo y aprender mucho de Ruby, y creo que para esto me va a ayudar el siguiente libro.

Siguiendo los tips o recomendaciones que vienen en Pragmatic Thinking & Learning espero poder ser un poco más organizado con mi conocimiento, con mis horas de estudio y también mejor enfocado. En el sitio de Pragmatic Programming books hay unos pdf’s de prueba de los primeros dos capítulos.

Si alguien de plano quiere comprar estos libros, por favor comprenlos a través de las ligas que están aquí así me ayudan a mantener este sitio, o bien me ayudarían a comprar más libros, aunque si alguien no quiere comprar pero desea patrocinarme un libro, una cerveza o un café, o sólo donar un pesito, o un dolar, pues les agradeceré enormemente que la donación la hagan por aquí.

Caray, lo que tiene uno que hacer por un libro o una cerveza, en este preciso momento me estoy imaginando como uno de esos borrachitos que andan en la calle pidiendo una moneda para seguir comprando alcohol pero en un estilo tecnológico :D , y bueno, si me unas cervezas, les puedo decir que les saldré bien barato porque con 6 ya estaré bien ebrio.

Instalando RoR 2.2 RC2 en Leopard

Al día de hoy no tengo una computadora a mi disposición, y como no tengo una, de vez en cuando hago cosas en la compu del trabajo, que no debería, y también a veces me prestan la macbook air, y en la macbook puedo trabajar un poco más, que me gustaría trabajar mucho más en la macbook, pues bien, hace rato ya había trabajado con Ruby on Rails con la versión que trae el leopard, pero hace unos días me dieron ganas de probar la RC de RoR la 2.2 (ya la RC2), para instalarlo tuve que investigar un poquito, ya que no es un proceso de instalación sencillo, tiene algunos trucos, para esto me basé en el post de Dan Benjamin, pero para variar me hago un resumen a mi mismo, para cuando se me vuelva a ofrecer, así que para más detalle visitar el post, ahí si mencionan que sólo por las dudas sería bueno respaldar la información, yo no lo hice, y todo salió bien.

Pues bien, para tener instalada una de las últimas versiones de RoR y diferente a las que está instalada por defecto en leopard es necesario tener instalado el XCode 3.0 o superior, este puede ser bajado de developer.apple.com o bien instalándolo del disco que viene con la mac, la verdad no se que disco es, pero con la mac debe de venir un disco (o más no recuerdo).

Primeros pasos

Primero que nada hay que configurar el path, para esto habrá que abrir una terminal (en este caso con el bash shell), y verificar que esté en mi directorio home, o bien esto puedo realizarse usando el comando:

cd

Habrá que editar el archivo .bash_login, yo lo hice con el vi, es posible que este archivo no exista, si no existe lo vamos a crear, y si existe pos editaremos la parte del path, entonces para editarlo o crearlo es con el siguiente comando:

vi .bash_login

Al final del archivo se deberá introducir la siguiente línea:

export PATH="/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin:$PATH"

Lo siguiente es ejecutar el cambio:

. .bash_login

Al path se agregó la ruta donde se encuentra MySQL, para la instalación de MySQL en leopard recuerdo que sólo bajé el paquete directamente de www.mysql.com y seguí las instrucciones que vienen con dicho paquete.

Se tiene que crear ahora un directorio donde vamos a bajar Ruby y posteriormente compilarlo, entonces habrá que ejecutar los siguientes comandos:

sudo mkdir -p /usr/local/src
 
sudo chgrp admin /usr/local/src
 
sudo chmod -R 775 /usr/local/src
 
cd /usr/local/src

Ruby

Para bajarlo y compilarlo ejecutamos los siguiente:

curl -O ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p287.tar.gz
 
tar xvzf ruby-1.8.6-p287.tar.gz
 
cd ruby-1.8.6-p287
 
./configure --enable-shared --enable-pthread CFLAGS=-D_XOPEN_SOURCE=1
 
make
 
sudo make install
 
cd ..

Para verificar que ruby se instaló en el path correcto, escribir:

which ruby

Se debería ver:

/usr/local/bin/ruby

RubyGems

El siguiente paso es instalar RubyGems (que por cierto Ruby on Rail 2.2 RC2 requiere de RubyGems 1.3.1):

curl -O http://files.rubyforge.mmmultiworks.com/rubygems/rubygems-1.3.1.tgz
 
tar xvzf rubygems-1.3.1.tgz
 
cd rubygems-1.3.1
 
sudo /usr/local/bin/ruby setup.rb
 
cd ..

Ruby on Rails

Para instalar la versión estable de RoR se ejecuta:

sudo gem install rails

También instalamos mongrel y capistrano, por si las moscas:

sudo gem install mongrel
 
sudo gem install capistrano

Ahora si, para instalar la versión 2.2 RC2 de RoR ejecutar:

sudo gem install rails -s http://gems.rubyonrails.org

Y por último instalamos la gem para mysql

sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql

Recursos:

http://danbenjamin.com/articles/2008/02/ruby-rails-leopard

http://weblog.rubyonrails.com/

http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-5.0.67-osx10.5-x86_64.dmg/from/pick#mirrors