Monthly ArchiveOctubre 2006
Software Libre & Sociedad 19 Oct 2006 02:27 pm
Diferencias al cambiar a un trabajo más creativo.

Cosas que han cambiado desde hace un año que dejé:
Mi puesto bien remunerado y en un entorno de esos de para toda la vida en una empresa del sector energético español.
Por:
Un puesto de resposable de I+D en una PYME que se llama Peopleware.
1.- Mi sueldo.
Ha bajado a la mitad. Es verdad que antes estaba bien pagado pero tengo la suerte de no tener muchas letras ni muchos vicios.
2.- Mi horario.
Antes debía estar (que no ser) ocho horas mínimo. Incluso llegué a pedir tiempo para dar unas clases en una universidad y no les pareció bien a pesar de que podría ser publicidad interesante.
Ahora lo pactado son seis horas al día que luego son más, pero no me cansan y las hago cuando quiero.
3.- Mi ubicación.
Antes siempre al mismo edificio.
Ahora elijo yo. Si tengo que ver a algún cliente me desplazo allí; puedo estar en las oficinas y durante meses he estado trabajando y programando desde mi casa. También he aprovechado para trabajar en bibliotecas municipales (qué fenomenal entorno de trabajo). Un tema que me ha gustado es que gracias a mi condición de doctorando en la UNED ésta me ha facilitado un tiempo un despacho con conexión a internet y unas estupendas vistas a la sierra madrileña.
4.- Mi formación
Antes entregaba unos planes de formación que no se sabía, por cuestiones variopintas, cuándo podría recibirse (en caso de recibirse).
Ahora tardamos en evaluar la asistencia a un curso o la suscripción a una revista o la compra de un libro menos de un minuto. En el libro de estilo está claro que apostamos por la formación y por eso la burocracia para este tema está reducida. Al poco de entrar vimos un curso de ACE interesante en Holanda y tras charlarlo media hora sacamos la tarjeta Visa de empresa y sacamos avión, hotel y curso. Sé mucho más de C++, frameworks y patrones, y además aplico directamente esos conocimientos.
Como formación más personal pero complememtaria he empezado a hacer el doctorado en Ingeniería del Software, porque tengo más y mejor tiempo libre.
5.- Conocidos y Conocimientos.
Antes yo era un cliente y así me veían los proveedores que además eran de empresas muy tradicionales. Poca innovación en general pero conocí gente muy interesante en cuatro años.
Ahora he conocido a personas muy brillantes por menos restringidas, por trabajo a gente de unas cinco universidades españolas, gente con proyectos dispares pero llenos de ilusión, participo en proyectos en red, hemos abierto proyecto de software libre en sourceforge, he trabajado codo con codo con antiguos proveedores, he abierto una bitácora personal y otra de proyectos, participo con entradas en la Pastilla Roja, hemos dado una charla en la Campus Party 2006 de Valencia, hemos ido al Ministerio de Industria a presentar nuestro proyecto, nos han concedido una subvención.
6.- Mi tiempo
Antes me organizaba alrededor del trabajo.
Ahora me organizo todo como quiero. “¿Un tenis a las 11:00? Vale, pero a las 16:00 sigo currando.”
7.- Vestuario.
Antes iba casi siempre de traje y el “casi” luchando contra corriente.
Ahora voy adecuado para la ocasión. Traje sólo cuando vas a clientes obligados a lo mismo, para no faltar. Voy cómodo y he renovado vestuario de camisetas.
8.- Jerarquías.
No es que yo sea muy dócil pero el ambiente era muy jerárquico y he visto cosas indescriptibles.
Ahora nos basamos en ideas. Las jerarquías aparecen en forma de responsabilidades y sólo se sacan los galones cuando no hay consenso y hay que tomar una decisión. Buscamos efectividad.
9.-Sensaciones.
Antes fue muy interesante los primeros años. Los últimos siguieron la humana tendencia a burocratizarse y a aplastar la creatividad y el dinamismo.
Ahora me pasa que me tiro seis horas currando del tirón y no me doy ni cuenta. Mucha más creatividad porque le ves potencial de aplicación.
Resumiendo creo que lo mejor en realidad ha sido dar el paso porque tengo menos miedo a dar otros. Relativizas las cosas. Tendemos - tiendo - a pensar y a compararme con los que me rodean y quizás me estoy comparando mal, con quien no debo.
Medirse con los demás la diagonal de la pantalla de tu televisor, después de todo no es tan importante, y si no ves la tele…
Ideas 19 Oct 2006 01:24 am
Curiosidad
He leído un artículo pero que muy interesante aquí.
Cito (in english, my excuses):
curiosity is the single most important attribute in a world that requires continuous learning and unlearning just to keep up
Arquitectura de Software 16 Oct 2006 06:32 pm
Patrones: Reactor
Este patrón es uno de los bonitos si tu proyecto tiene que ver con el par problema/solución en el que es aplicable. El Reactor está especialmente indicado en aplicaciones que deben responder ante diferentes eventos de forma que no tengamos que preocuparnos por el típico bucle de espera de eventos que luego deben ser despachados al método o función adecuados.
La idea es tener todo un esqueleto hecho (volvemos a ser vagos) y sólo programar la parte específica de la aplicación. De esta forma primero registramos en pares evento-manejador de evento, y luego es el Framework que implementa el patrón el que nos llama cuando ha habido una ocurrencia de algo a lo estábamos registrados.
Esto es lo que se llama inversión de control: No somos nosotros los que llamamos, es el framework el que lo hace.

Descripción
Es un patrón de arquitectura que nos permite a aplicaciones orientadas a eventos demultiplexar y despachar las peticiones de servicio que llegan desde uno o más clientes.
Contexto de uso
En Osmius tanto en el Centro de Supervisión como en el Agente Maestro se repite la situación que nos permite aprovecharnos de este patrón. Ambos procesos tiene un servicio para la recepción de mensajes a través de varios sockets. En el caso del centro de supervisión recibiremos conexiones y datos de múltiples agentes maestros y, en el caso de éstos últimos, recibirán peticiones de conexión y de envío de mensajes de los agentes gestionados.
Los agentes también manejan varios orígenes de eventos como son los sockets para la recepción de órdenes y un nuevo tipo de origen constituido por las expiraciones de los contadores de tiempo asociados a los periodos de monitorización de las diferentes variables de las instancias monitorizadas.
Necesitamos quedarnos a la espera de la aparición de eventos en determinados recursos, detectar su aparición, enviar o despachar su tratamiento a los métodos adecuados y realizar el tratamiento adecuado en cada caso.
Además de nuevo nos encontramos con el requerimiento multiplataforma y la deseada reusabilidad, con lo que programar los mecanismos de demultiplexación de forma fija para determinada plataforma nos impedirá alcanzar los objetivos además de perder tiempo y recursos.
Beneficios en el caso de Osmius:
- Reutilización del código no específico.
- Claridad de separación de demultiplexación y despacho de eventos, de su tratamiento. Nos centramos en codificar éste último.
- Portabilidad.
Ejemplo de Uso
En este patrón hay que cambiar la mentalidad típica de programación de aplicaciones en las que es la aplicación la que programa el bucle de captura de eventos y se encarga de llamar de manera activa a las funciones para el tratamiento de cada evento.
Este patrón y el framework en que se encuadra dentro de Osmius implementan inversión de control. Por inversión de control entendemos que es el framework el que llama a determinados métodos gancho de objetos que habremos previamente registrado con el Reactor, al ocurrir los eventos.
En el caso de los eventos Osmius que deben ejecutarse al vencer determinado periodo de tiempo lo primero que hacemos en crear nuestra clase haciendo que sea derivada de ACE_Event_Handler utilizando la herencia.
class OSM_Event : public ACE_Event_Handler
{
public:
// Constructor al que le pasamos un reactor por si queremos uno distinto del de
// por defecto.
OSM_Event (ACE_Reactor *r= ACE_Reactor::instance());// Método gancho que se llama siempre así que será llamado cuando expiren los contadores
// de tiempo registrador.
// ACE_Time_Value es otra clase de la Wrapper Facades para encapsular el tratamiento de
// tiempos y fechas de forma portable.
virtual int handle_timeout (const ACE_Time_Value &tv,
const void *);
// Tratamiento específico de inicialización para Osmius.
int open(const ACE_TCHAR* name, const OSM_Instance_Base* instance,
const int interval , const int i_delay);// Cierre del objeto.
int close(void);// Método gancho llamado cuando este objeto se saca del framework del reactor y es
// destruido.
virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
ACE_Reactor_Mask = 0);private:
..........
..........
..........
};
En la implementación de handle_timeout() ponemos el tratamiento específico de nuestra aplicación, en nuetro caso ejecutamos la acción contra la instancia que nos devuelve un valor que metemos en un mensaje que le pasamos al manejador de mensajes MsgManager a través de su método put().
int
OSM_Event::handle_timeout(const ACE_Time_Value &tv, const void *)
{
......
......
ACE_Time_Value time_before = ACE_OS::gettimeofday();
// Creamos el mensaje y le ponemos los campos iniciales
OSM_Message* osmius_message=0;
ACE_NEW (osmius_message, OSM_Message);
osmius_message.typ_message ("N", 1);
......
......
ACE_Time_Value time_after;
// Ejecutamos la acción que sea contra la instancia y recuperamos el valor en “value”.
this->action_.execute(this->cmd_line_,ACE_OS::strlen(this->cmd_line_),
this->timeout_,
val_text ,
&val_len , &value )// Ponemos el OSM_Message dentro de un objeto ACE_Message_Block para su envío.
ACE_Message_Block* mblk=0;
mblk = (ACE_Message_Block*) &osmius_message;
// Prepare the message to be sent.
osmius_message->encode();// Enviamos el mensaje al agente maestro o donde lo envíe ins_manager con put().
// The pointer to the instance manager is in our osm_instance owner.
this->osm_instance_->ins_manager()->put(mblk,0)return 0;
};
Por último tenemos que registrarnos con el reactor para que nos llame cada vez que venza el periodo de tiempo (interval) asignado al evento.
int
OSM_Event::open(const ACE_TCHAR* name, const OSM_Instance_Base* instance,
const int interval, const int i_delay);
{
ACE_OS::strncpy(this->name_, name,OSM_Message::CODLEN);
this->cod_message_[OSM_Message::CODLEN]=0;
this->osm_instance_ = instance;if (interval > 0)
this->interval_ = interval;
else
this->interval_ = 5;if (initial_delay > 0)
this->initial_delay_ = initial_delay;
else
this->initial_delay_ = 5;// Nos registramos con el reactor a través de la llamada para contadores de tiempo
// que se llama schedule_timer().
ACE_Time_Value tv_interval(this->interval_);
ACE_Time_Value tv_delay(this->initial_delay_);
this->reactor()->schedule_timer(this, 0, tv_delay,tv_interval)
......
......return 0;
}
Si queremos aplicar este patrón orientado a cuando se reciban datos de red en determinado socket como es el caso en el servicio que recoje los mensajes en el Master Agent para a su vez enviarlos al Centro de Supervisión:
Declaramos la clase.
class ACE_Svc_Export OSM_MA_MsgReceiver
: public ACE_Svc_Handler
// Derivamos de ACE_Svc_Handler que es a su vez derivada de ACE_Event_Handler utilizando
// templates para indicar que utilizaremos sockets para la comunicación y que no queremos
// sincornización ya que no vamos a utilizar en este caso multihilo.
{
public:
// Constructor.
OSM_MA_MsgReceiver (OSM_MA_MsgSender *handler = 0)
: msg_sender_ (handler) {}// Método gancho de inicialización que será llamado cuando un agente haga una nueva
// conexión.
virtual int open (void *);// Método gancho para cierre y para desregistrarse con el reactor.
virtual int close (u_long = 0);protected:
// Método gancho que se llamará cuando un cliente (agente) tenga un mensaje que
// enviar (con send()).virtual int handle_input (ACE_HANDLE handle);
// Método gancho que se llama cuando un cliente termina.
// Cerramos el socket y quitamos el cliente de “connected_clients_”.
virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
ACE_Reactor_Mask = 0);// Puntero al servicio MessageSender.
OSM_MA_MsgSender *msg_sender_;// Lleva la cuenta de los descriptores de los clientes conectados.
ACE_Handle_Set connected_clients_;
};
Registro con el Reactor para cuando hay datos en el socket en el método open():
int OSM_MA_MsgReceiver::open (void *)
{
ACE_HANDLE handle = peer ().get_handle ();
if (reactor ()->register_handler
(handle, this, ACE_Event_Handler::READ_MASK) == -1)
return -1;
connected_clients_.set_bit (handle);
return 0;
}
Tratamiento en handle_input():
int OSM_MA_MsgReceiver::handle_input (ACE_HANDLE client_handle)
{
ACE_Message_Block *mblk = 0;
OSM_MsgHandler message_handler(client_handle);// Creamos un bloque para poner el mensaje y enviarlo luego.
if (-1 == message_handler.recv_message (mblk))
{
return -1;
}// Enviamos el mensaje.
if (-1 == msg_sender_->put(mblk))
{
// Could not put the message.
mblk->release ();
return -1;
}mblk->release ();
return 0;}
El patrón Reactor dentro del framework que proporciona ACE se utiliza extensamente en Osmius para envío y recepción de datos a través de sockets, capturar expiraciones de contadores del tiempo y para recoger llamadas desde señales como la pulsación de Control-C por un usuario.
Arquitectura de Software 14 Oct 2006 09:56 am
Patrones: Envoltorio
Hace ya tiempo empecé una serie de entradas sobre la reusabilidad en el proceso de elaboración de software. Desde el “Copiar y Pegar”, pasando por middlewares, frameworks y finalmente los Patrones de Diseño. Mi idea es seguir con algunos de los patrones que más estamos utilizando en Osmius utilizando el proyecto como ejemplo de uso.

Introducción
Uno de los patrones más extendidos en el desarrollo de software que intentas que sea multiplataforma es el Patrón Wrapper Facade, que traduciría como Fachada o Envoltorio. Lo que pretende este patrón es separar diferentes implementaciones de una misma funcionalidad de manera que podamos utilizar esa funcionalidad siempre de la misma forma.
Los sistemas operativos tienen la manía de estar estructurados de formas distintas entre ellos y de proporcionar llamadas al sistema con nombres, parámetros y estructuras diferentes. Suponed que quiero calcular la carga de la cpu; la pregunta es ¿En Linux? ¿En Windows? ¿En qué?. Bueno, la respuesta ideal aquí es “me da igual“. Esto sería porque alguien hubiera desarrollado un envoltorio que que encapsula esas diferencias de forma que tengo un interfaz único (ENVOLTORIOS_VARIOS::dime_la_carga_de_cpu(int carga)) no dependiente de las APIS suministradas en capas más bajas.
Descripción
Es un patrón de diseño para encapsular las funciones y datos proporcionados por APIs existentes no orientadas a objeto, dentro de interfaces de clases orientadas a objeto aportando los beneficios de ser más concisas, robustas, mantenibles y portables.
Contexto
Dos de los tres principales componentes de Osmius como son el Agente Maestro y los Agentes para la monitorización de variables en las diferentes instancias tienen como requisito claro el poder ejecutarse en diferentes plataformas hardware y de sistema operativo. Necesitamos poder distribuir nuestro código y compilarlo (estamos tratando con C++) en por ejemplo, Linux, Windows y Solaris sin modificaciones o con muy poco trabajo extra.
Al ser Osmius una aplicación distribuida en red hace uso de las llamadas del SO para comunicaciones en red a través de sockets y otros mecanismos, de llamadas para el tratamiento y lectura de ficheros, de mecanismos para el lanzamiento, control y terminación de procesos e hilos, y de funciones para demultiplexar la ocurrencia de eventos en conjuntos de uno o varios recursos.
Estas funcionalidades suelen estar disponibles a través de las APIs – normalmente en C no orientado a objeto – de los diferentes SO. Programar usando estas APIs es difícil de aprender, tedioso y poco portable.
ACE proporciona unos interfaces comunes en C para los diferentes SO, que luego encapsula mediante clases C++ aplicando el patrón Wrapper Facade que nos aporta los siguientes beneficios en el caso de Osmius:
- Sólo aprendemos una vez el interfaz en lugar de con cada SO.
- Portabilidad garantizada.
- Detección de posibles problemas con los tipos en tiempo de compilación.
- Podemos dejar para el tiempo de instalación e incluso de ejecución parámetros de comportamiento de los diferentes mecanismos.
Con este patrón nos evitamos el uso directo de las APIs de bajo nivel de los diferentes sistemas operativos.
Ejemplo de uso
Osmius utiliza las clases envoltorio que proporciona ACE para asegurarse que sus componentes corran en diferentes plataformas.
Por ejemplo al utilizar Osmius la ejecución de procesos en diferentes hilos necesita de mecanismos portables y con el mismo interfaz para garantizar la exclusión mutua en determinadas partes del código y en el acceso a recursos.
La clase que utilizamos es ACE_Thread_Mutex cuyos principales métodos tienen la siguiente interfaz:
int remove (void)
int acquire (void)
Acquire lock ownership (wait on queue if necessary).
int acquire (ACE_Time_Value &tv)
int acquire (ACE_Time_Value *tv)
int tryacquire (void)
int release (void)
La implementación del método acquire() para Solaris es:
int acquire(void) {
return mutex_lock(mutex_);
}
,y existen implementaciones para otras APIS como VxWorks, LynxOS, Windows o hilos POSIX.
El uso dentro del código es:
ACE_Thread_Mutex osmius_mutex;
.....
osmius_mutex.acquire();
.....
funcion_protegida_y_sincronizada();
......
osmius_mutex.release();
Otras clase Wrapper Facade de ACE que usamos en Osmius encapsulan las llamadas para Sockets, gestión de procesos e hilos, operaciones de tiempo, etc.
El uso de este patrón está muy extendido en Osmius y las propias clases de ACE se basan en él para proporcionar servicios de más alto nivel, permitiendo un uso implícito sólo por usar algunos de los frameworks que ACE proporciona.
Software Libre 10 Oct 2006 09:45 am
Automegabombo
Vamos con varias noticias relacionadas con el proyecto Osmius. Tenemos mucho ruido, así que hay que apretar y tener nueces, no sea que nos pasemos de ideas y no concretemos ni curremos como decíamos en la anterior entrada.

Tenemos dede hace tiempo activa la página web del proyecto Osmius.
Además estamos escribiendo un blog.
Además se publica un artículo de título “Osmius: Software de Calidad ‘Made in Spain’ en la Revista del Círculo de usuarios de Oracle de España, que estará en lo quioscos este mes de octubre.
Ideas 06 Oct 2006 01:29 pm
Creatividad y diarrea mental
Últimamente me encuentro metido en foros y grupos en los que hay personas con una gran capacidad para tener ideas.
Siempre he creído que parir ideas es lo suyo independientemente de que las lleves a cabo o no: “Si tengo mil ideas al final haré una o dos” ha sido siempre mi argumento, porque eso es mejor que no tener ideas per sé, y por tanto no emprender proyectos.
La vida, dicen, consiste finalmente en tener proyectos. Sin proyectos, sin ilusiones no eres feliz.

Pero a pesar de esto creo que tener ideas está bien, pero mucho mejor es llevarlas a buen término, currártelas. Tener ideitas y que se las curren otros no es lo mismo ni se puede ponderar igual a la hora de pesos o repartos, mírese según sea el caso.
Es por esto que estoy de acuerdo con Ricardo Galli en la extensa entrevista que le hacen en diario de ciencia y tecnología La Flecha.
Cito:
Lo que noto es que hay una especie de sobrevaloración de las ideas, como si fuesen suficientes por sí solas y no sólo una condición necesaria para luego ponerlas en marcha. Así es típico oir “es que tales y tales roban las ideas y las ponen en marcha” o “nosotros tenemos ideas y ellos se forran”. Creo que hay que dejar de darles tanta importancia a las ideas y asumir que lo importante y difícil es ponerlas en marcha y que funcionen. Que no basta con tener un día inspirado, hay que currárselo también.
Además también me pasa que estoy a mil temas y no aprieto suficiente en 999 o 1000. (A ver ese Osmius)