Pensando la solución a este problema, ideé que el mejor sistema es
un sistema remoto automático de última tecnología ;-) montar un
servidor web específico que al acceder a una página del mismo,
interrumpiera mi programa y pasado un tiempo, volviese a ponerlo en
marcha. Como se vé, no consiste en impedir que los demás usuarios
tengan acceso a el ancho de banda disponible, es más bien, un sistema
para que no sea necesario tener que reactivar los servicios que me
interesaban.
Buscando como programar un minúsculo servidor web, estuve viendo
diversas posibilidades, pero la comunicación en red no es siempre
fácil de programar. Así que me decidí darle una oportunidad a Catalyst
(un framework de desarrollo rápido para Perl, similar en algunos
conceptos al Ruby on Rails).
Sirva este artículo como una muy muy breve introducción a Catalyst.
Catalyst construido para seguir el esquema Modelo-Vista-Controlador.
El modelo es la forma de almacenar los datos que define la información
de nuestro sistema, generalmente es un interface a una base de datos.
La vista se encarga de generar la presentación o interface con el
usuario. Y el controlador se encarga de unir la interacción efectuada
en la vista con la información almacenada en el modelo.
Para nuestra pequeña aplicación, no vamos a usar ni datos ni
vistas, solo un controlador.
Pero, primero, lo primero:
Instalación de Catalyst
En la mayoría de las distribuciones modernas ya debe de estar incluido
Catalyst. Así que en mi vieja debian, solo es necesario usar:
#apt-get install libcatalyst-perl
El que quiera estar a la última, puede bajarselo desde CPAN o incluso
desde CVS.
$ perl -MCPAN -e 'install Bundle::Catalyst'
Generando el esqueleto de nuestra aplicación
Catalyst tiene una serie de script para simplificar las tareas
repetitivas de creación de nuevos sitios. Por lo tanto, para crear un
nuevo sitio, sólo es necesario pedirle a catalyst que nos haga el
favor:
$ catalyst.pl Pausando
Nos creará una estructura de subdirectorios. Las distintas
funcionalidades dentro de nuestro servidor, se reconocen
automáticamente al escanear en el arranque que ficheros se encuentran
en que directorios.
Si queremos crear una nueva vista con salida pdf, bastaría con
pedirle amablemente a catalyst que nos creara el esqueleto de dicha
vista:
$ cd Pausando
$ script/create.pl vista salida.pdf
Cómo funciona Catalyst
Catalyst descompone la url que se le solicita determinando la
acción a desarrollar y los parámetros que se le pasan. Ejecuta la
petición adecuada a la base de datos y transfiere la información
determinada a la vista, para su representación.
Catlyst se puede ejecutar usando Apache con mod_perl, como CGI o
(lo que usaremos nosotros) como un servidor web stand-alone. Para este
último caso, existe un script (script/server.pl) que lo pone en marcha
a nuestra disposición.
Nuestro programa «Pausando»
El funcionamiento de nuestro programa es el siguiente: Cuando se
accede a nuestro servidor, se detiene nuestro programa, si se intenta
acceder a nuestro servidor cuando el programa consumidor está parado,
se informa del tiempo que queda para su reactivación. Cuando pasa el
tiempo anunciado, se pone el programa en marcha otra vez. Además,
queremos tener un log de las veces que se a detenido nuestro programa
a lo largo del día.
En mi caso, no voy a añadir ninguna Vista, los mensajes serán
simplente texto plano que todos los navegadores entienden. Catalyst se
encarga de proporcionar las cabeceras adecuadas.
Vamos al directorio lib y editamos el programa principal:
Pausando.pm. Es un fichero muy pequeño donde se definen la versión del
programa (por defecto 0.01), el nombre (Pausando, el que nosotros le
dimos), y donde está los fuentes de nuestro programa. Viene definido
una acción por defecto para que podamos comprobar que nuestro servidor
funciona. Si ejecutamos script/server.pl y accedemos a
http://localhost:3000/ lo veremos.
Por defecto, Catalyst, tiene activado la información de Debug, esta
es muy útil mientras estemos desarrollando, simplemente quitando la
opción -Debug en la linea de Pausando.pm que carga el paquete
Catalyst, esta información desaparecerá
Nosotros vamos a borrar el contenido de default por nuestra propia
función. y ya habremos acabado. Voy a incluir el fichero completo
Pausando.pm ya que no es muy largo:
package Pausando;
use strict;
use Catalyst;
#use Catalyst qw/-Debug/;
our $VERSION = '0.01';
my $tiempo=10;
my $MyStart='echo "Me puse en marcha"';
my $MyStop='echo "Me paré"';
Pausando->config(
name => 'Pausando',
root => '/home/jamarier/Catalyst/Pausando/root',
uinicio => time - 1 - $tiempo,
);
Pausando->setup;
sub default : Private {
my ( $self, $c ) = @_;
my $lleva = time - $c->config->{uinicio};
if ($lleva > $tiempo + 1)
{
$c->stash->{salida} = "Se puso el contador en marcha";
$c->log->info("Activado en ".($lleva+$c->config->{uinicio}));
$c->config->{uinicio}= time;
if (!fork)
{
system($MyStop);
sleep $tiempo;
system($MyStart);
exit 0;
}
}
else
{
$c->stash->{salida} = "El sistema ya está parado, aun le quedan ".
($tiempo-$lleva+1) ." segundos.\n";
}
$c->res->output($c->stash->{salida});
}
=head1 NAME
Pausando - Una muy simple aplicación, pausa un programa/servicio durante un
tiempo. Acceso por web.
=head1 SYNOPSIS
En el directorio base, ejecutar script/server.pl. Acceder via web usando
el puerto 3000 del equipo.
=head1 DESCRIPTION
No hay mucho más que decir. Descrito en Libertonia en una historia llamada:
«Mini-intro-Tutorial de Catalyst»
=head1 AUTHOR
Javier M Mora (jamarier), realizado en Agosto de 2005
=head1 LICENSE
This library is free software . You can redistribute it and/or modify
it under the same terms as perl itself.
=cut
1;
Las modificaciones son:
- añadidas 3 líneas con tres constantes útiles para el programa: el
tiempo (en segundos) que se detendrá el nuestro programa consumidor de
ancho de banda, el nombre del script que se encargará en nuestro
servidor de parar dicho programa, y el nombre del script que se
encargará de volver a ponerlo en marcha.
- añadido 1 línea en las variables de configuración del sistema para
definir un valor inicial a la variable que controla el tiempo que pasó
desde la última petición de detención
- Escritura desde cero de la acción a efectuar. (23 líneas)
efectuando en este caso un fork en el cual el hijo se encarga de parar
y poner en marcha la utilidad controlada
Algunos comentarios sobre el código:
- Dado que se trata de un servidor, la estructura de datos se
construye para que tenga sentido para cada cliente que accede a
nuestro servidor. Esto se observa en el hash de contexto %c. Toda la
información está presente en este hash: $c->stash es una zona de
almacenamiento de memoria volatil de la sesión que permite comunicarse
entre distintas llamadas dentro de catalyst. En este caso, aunque
hemos definido $c->stash->{salida}, no era extrictamente necesario su
uso, ya que no es usado en ninguna otra parte. Si en vez de dar la
salida nosotros mismos, hubiesemos requerido a un objeto Vista su
representación, en ese caso sí sería necesario hacerlo tal y como
hemos indicado.
- Por otra parte, las variables situadas en el subhash $c->config,
son comunes a todas las sesiones dadas por Catalyst. Es por ello que
el tiempo de inicio de la última pausa, sea declarada en ese espacio.
Dado que no debemos intentar parar o ejecutar el mismo programa de
forma simultánea por varias personas a lo largo de la misma red.
- $c tambien nos suministra un sistema de bitácora, que nos permite
registrar detalles interesantes. tenemos $c->log->info(),
$->log->warn(), $c->log->debug() y otros.
- Una vez terminadas las pruebas se puede desactivar la opción de
debug.
- Aunque el servidor stand-alone suministrado dicen que no tiene el
rendimiento del Apache, en este caso al tratarse de una aplicación
para una red local de 4 elementos y dicho servidor no tener salida a
internet, considero que es más que suficiente el servidor. (y así nos
ahorramos el tener que instalar y configurar Apache).
- Como posibles mejoras, el aspecto del interface es deplorable, Se
pueden generar páginas HTML y con el modelo Vista adecuado, Hacer que
se muestre una página más interesante. Escribiendo este artículo, he
visto que Catalyst da soporte a AJAX, de forma que se podría crear una
página que informara en tiempo real del tiempo que falta para terminar
la pausa y con un botón para prolongar dicho tiempo.
Para más información
Ambas direcciones, tienen enlaces a ejemplos, documentaciones, videos,
tutoriales y otras introducciones.