Monday, August 13, 2007

Rake y tareas de mantenimiento

Rake es una excelente herramienta que nos permite automatizar operaciones usando código Ruby y Rails. Salvando algunas diferencias, Rake es para ruby lo que make para C/C++ o Ant para Java.
Permite definir un serie de operaciones y asociarlas a una etiqueta. De manera que podemos ejecutar la secuencia simplemente escribiendo rake mi_etiqueta.

En nuestro último proyecto, hemos creado un fichero Rake con una serie de operaciones de mantenimiento. Entre otras, una tarea para borrar las sesiones que han expirado, y por otro lado una tarea para producir un informe con estadísticas de la información guardada en nuestra base de datos.

Las tareas rake en un proyecto Rails se encuentran en el directorio lib/tasks. En nuestro caso crearemos el fichero mantenimiento.rake en ese directorio.

La definición de una tarea rake es muy sencilla e incluye una descripción y la tarea en sí:


desc "Descripción de la tarea"
task :mi_tarea do
##Secuencia de operaciones
end

Tarea para eliminar las sesiones no utilizadas

En nuestro proyecto utilizamos la base de datos para almacenar las sesiones de usuario. Para activar esta opción de Rails tan sólo hay que editar el fichero config/environment.rb y cambiar el valor de la variable config.action_controller.session_store a :active_record_store. Posteriormente debemos ejecutar rake db:sessions:create. Como podéis ver utilizamos una tarea rake definida por Rails para la creación de la tabla que guardará las sesiones. No olvidés de dar el valor correcto a la variable de entorno RAILS_ENV si no trabajáis en el entorno por defecto, que es development.

Ahora concentrémonos en la tarea rake:


desc "Borrar de la base de datos la sesiones que han expirado ."
task :borrar_sesiones_expiradas => :environment do
puts "Removing old sessions from #{ENV['RAILS_ENV']} database" unless ENV['SILENT']
CGI::Session::ActiveRecordStore::Session.delete_all("UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(updated_at) > 3600")
end

Esta tarea rake simplemente borra todas las sesiones que no han sido actualizadas en la última hora. Para acceder a un modelo ActiveRecord desde una tarea rake debemos referenciar el modelo CGI::Session::ActiveRecordStore::

Tarea para crear un informe con estadísticas


desc "Informe de estadísticas"
task :informe => :environment do
interval = (ENV['REPORT_INTERVAL'] || 4).to_i
interval = 4 if interval == 0
puts "Número de canales #{CGI::Session::ActiveRecordStore::Channel.count}"
puts "Número de usuarios #{CGI::Session::ActiveRecordStore::User.count}"
puts "###Usuarios registrados en las últimas #{interval} hours"
users = CGI::Session::ActiveRecordStore::User.find(:all,
:conditions => "UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(created_at) < #{interval}*3600", :order => "created_at asc")
if users.size > 0
puts "id | email | nickname | creado el"
users.each {|user| puts "#{user.id} | #{user.email} | #{user.nickname} | #{user.created_at.iso8601}"}
else
puts "Ninguno"
end

puts
puts
puts "###Canales creados en las últimas #{interval} horas"
channels = CGI::Session::ActiveRecordStore::Channel.find(:all,
:conditions => "UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(created_at) < #{interval}*3600", :order => "created_at asc")
if channels.size > 0
puts "id | propietario | nombre | impressiones | crt | blog url | creado el"
channels.each {|channel| puts "#{channel.id} | #{channel.user.email} | #{channel.title} | #{channel.impressions_count} | #{"%.2f" % (channel.impressions_count > 0 ? (channel.clicks_count*100).quo(channel.impressions_count) : 0)}% | #{channel.url.url} | #{channel.created_at.iso8601}"}
else
puts "Ninguno"
end

puts
puts
puts "###Canales más populares###"
channels = CGI::Session::ActiveRecordStore::Channel.find(:all,
:order => "impressions_count desc",
:limit => 10)
if channels.size > 0
puts "id | propietario | nombre | impressiones | crt | blog url | creado el"
channels.each {|channel| puts "#{channel.id} | #{channel.user.email} | #{channel.title} | #{channel.impressions_count} | #{"%.2f" % (channel.impressions_count > 0 ? (channel.clicks_count*100).quo(channel.impressions_count) : 0)}% | #{channel.url.url} | #{channel.created_at.iso8601}"}
else
puts "Ninguno"
end

end

Para ejecutar las tareas rake, hay que ir al directorio raiz de nuestra aplicación rails y ejecutar rake mi_etiqueta:
rake borrar_sesiones_expiradas
rake informe

Para el entorno de producción:
RAILS_ENV="production" rake borrar_sesiones_expiradas
RAILS_ENV="production" rake informe


0 comments:

Post a Comment