Archivo de la categoría: General

Speaker en la Commit Conf 2024

El próximo sábado 20 de abril, tengo el placer de dar una charla en la Commit Conf 2024. La charla será  «La nueva forma de expresar ‘Data’ en Java 21» y tratará sobre como con el nuevo soporte de los tipos algebraicos que se ha dado en Java 21 se ofrece de facto la nueva forma de expresar Data  en Java desde JavaBeans una especificación que se puede decir sin miedo que es del siglo pasado.

Será el sábado después del descanso de la comida.

Charla en MadridJUG/Madrid GUG sobre tipos algebraicos en Java 21

El pasado 24 de octubre dí una charla sobre el soporte completo que se ha dado en Java 21 a los tipos algebraicos. Estuvo muy bien, sobre todo por el debate que se estableció durante la charla y en el networking posterior.

Diapositivas presentación: Tipos algebraicos en Java 21

El repositorio de código:

  https://github.com/logicaalternativa/algebraictypes

y también el video del directo de la charla

Charla Commit Conf 2023 sobre programación funcional y patrones funcionales

El pasado 21 de abril di una charla sobre programación reactiva y como tener conocimiento de los patrones funcionales pueden ayudar a entender mejor este tipo de programación.

En la charla también introduzco el concepto de DSL (Domain Specific Language) que permiten de una manera real abstraer nuestro código de la tecnología escogida.

En otro orden de cosas, para mí fue un honor que la organización del Commit Conf confiara en mí para ser ponente.

Aquí están las diapositivas de la presentación

Presentación Commit Conf 2023Diapositivas presentación: Programación reactiva y patrones funcionales

y el vídeo de la charla

Notas sobre aprendizaje por refuerzo

El objetivo de este post es servir de introducción a una de las ramas del machine learning o, en español,  aprendizaje computacional como son los modelos de aprendizaje por refuerzo. Los sistemas de aprendizaje computacional se pueden modelar como una función que dependiendo del valor de unas entradas se obtiene una salida que permite predecir o clasificar.

# Modelización de un sistema de aprendizaje computacional como una función 

Entrada_1  -->  ,-------.
Entrada_2  -->  | Modelo| --> Predicción o clasificación (Salida)
 ...       -->  `-------'  
Entrada_n  

----
predicción = modelo( entrada_1, entrada_2, ..., entrada_n )

Aprendizaje por RefuerzoSi nos atenemos al conocimiento a priori de cuan buena puede ser la predicción, podemos clasificar los sistemas en tres grupos:

En los sistemas supervisados se tiene un conocimiento completo. Un ejemplo puede ser un clasificador que es capaz de distinguir entre un muffin o un chiguagua, ya que se puede saber (o puede que no sea tan sencillo 😀 ) si el clasificador lo ha hecho bien o se ha equivocado. Por el contrario, los sistemas no supervisados, no existe ese conocimiento previo y sirven para descubrir patrones y agrupaciones desconocidos dentro de un conjunto de datos.

El el punto medio están los sistemas de aprendizaje por refuerzo, donde sólo podemos saber si el sistema esta respondiendo mejor o peor con respecto a una entrada. Esto se materializa obteniendo una recompensa o una penalización del resultado de la salida, y así,  «saber» si la solución  plateada actual, va por el buen camino.

Un ejemplo en la vida real es un cachorro al que le estamos enseñando a sentarse, si lo hace bien, recibe su recompensa y si no, no recibe nada. Sin entender al principio lo que pasa, al cabo de unas cuantas veces pensará «Si en esta situación, me comporto de esta manera, recibiré una recompensa porque en el pasado ya me ha ocurrido».

Dentro sistemas de aprendizaje por refuerzo están los algoritmos genéticos utilizados en sistemas difusos. Cuando se habla de un sistema difuso se está hablando de un sistema del que no se tiene «incertidumbre» en la percepción del entorno. Hay que tener en cuenta que este tipo de conocimiento incompleto es muy común en el mundo real («velocidad en torno los 100 km/h», «temperatura mayor de 25ª»)  y nosotros los humanos somos muy capaces de tomar decisiones a partir de esta información imprecisa.

Con respecto a los algoritmos genéticos son aquellos que se van variando sus parámetros de modelo de una manera parecida a como funciona en la naturaleza. En esta,  aquellas familias de genes que mejor se adaptan al entorno son las que prevalecen y siguen evolucionado y en los algoritmos genéticos son las familias de parámetros que más se acercan a la solución óptima son los que prevalecen y a partir de los más exitosos  se sigue evolucionando.

Los agentes reactivos también pueden encajar dentro de los sistemas basados en aprendizaje por refuerzo. Un agente tiene un sistema autónomo que está puede obtener información y comunicarse con el mundo real

Reactivo significa que el agente no tiene una idea clara, ni una representación simbólica de entorno con el que se comunica. Es un  sistema sencillo que simplemente se relaciona y reacciona con su entorno. La inteligencia emerge de las iteraciones de varios de estos agentes.

Una hormiga se limita a reaccionar a su entorno comunicándose con otras a través del olor( feromonas),  físicamente o mediante sonido o vibraciones. La suma de estas interacciones hacen que el hormiguero sea un sistema altamente adaptativo e inteligente sin un sistema de control centralizado, con organizaciones complejas como la separación de tareas dentro de los individuos.

En próximas entradas quiero centrarme en este tipo de sistemas multiagente, que es un agente y su relación con los modelos de aprendizaje por refuerzo.

M.E.

Vídeo y diapositivas de la charla de Commit Conf

Los días 23 y 24 de noviembre ha tenido lugar en Madrid la primera edición del Commit Conf, uno de los eventos más importantes que se tiene en lengua castellana.

En su momento presente mi charla sobre Akka Sharding y su relación con DDD al “call for papers” con ilusión pero sin grandes esperanzas de que fuera aceptada. Hay que tener en cuenta que hasta ese momento no tenía experiencia presentando charlas en eventos públicos aunque afortunadamente si que tengo cierto callo en exponer ideas en público ya que mi trabajo me lo exige.

Así que cuando me aceptaron la presentación me lleve una enorme alegría porque consideraron el tema de mi charla interesante. Alegría, pero también responsabilidad por toda la confianza depositada.

Recuerdo con una sonrisa la primera presentación que hice a  a tres compañeros de trabajo que me hicieron de beta testers. Para mi alivio les resultó interesante y fue curioso, porque cada uno tenía una visión diferente de lo que le había gustado de la presentación. Uno se decantó más por las posibilidades que ofrecía este paradigma, otro puso más interés como se implementaba y el otro las implicaciones operacionales que tenía el despliegue de un sistema distribuido. El problema fue el tiempo: se fue más de hora y media.

Luego he tenido la increíble oportunidad de presentar la charla en otros foros como puede ser en el ScalaMAD (el 31 de octubre) a los que estoy agradecido y que me permitió pulir la charla.

Al final creo que la presentación en el Commit fue bastante bien, aunque recortada estuvo un poco justa de tiempo, … me faltaron unos minutos, un problema endémico por intentar tener en cuenta todos los conceptos, pero si que la gente se mostró participativa en la tanda de preguntas lo cual es muy bueno.

En resumen la sensación fue muy positiva, una experiencia intensa pero muy bonita de la que guardaré un buen recuerdo. Para terminar, lo prometido, estos son el vídeo y los enlaces de la charla y el repositorio del github de los notebook de Jupiter con la demo.

Presentación: Akka Sharind y su relación con DDD

Código: Repo GitHub

Actores tipados, Akka por ejemplos

«Tercer y último artículo sobre Akka explicado mediante ejemplos.

En los dos anteriores se basó en como funcionan la cola de mensajes de un actor, que es un router, como se envían mensajes entre actores. Después se trató temas como la supervisión y el bus de eventos.

Ahora me centraré en los actores tipados.«

Entrada anterior: Akka por ejemplos. Sobre supervisión, bus de eventos, …

Todo el código fuente relacionado con esta serie de posts está disponible en mi repositorio de GitHub

[Logo GitHub] AkkaActorsAndFutures


Actores tipados

Los actores tipados son una funcionalidad que ofrece Akka recubriendo un actor no tipado en un interfaz java. Con un actor tipado el programador realiza llamadas a un método de una clase normal ‘sin preocuparse‘ (y pongo esto entre comillas por lo que veremos más adelante) de lo que está detrás es un actor de Akka.

[Actor tipado]

[Actor tipado]

Permite unir los dos mundos, código java estándar con el mundo de los actores. En la documentación de Akka puedes leer que tienen su nicho, pero hay que ‘usarlos con moderación‘. Recomiendan que si lo que buscas es una arquitectura de alta escalabilidad utilizar estos actores no es la solución más sencilla. Por ejemplo en este caso, aunque se puede, no es tan natural la supervisión y la monitorización padre-hijo.

Para los actores tipados, Akka utiliza el patrón de Objetos Activos y proxys de Java. Para levantar un actor tipado es necesario una interfaz y una implementación. Simplificando, en los actores tipados no existe el método ‘onReceive()‘ y se utilizan como un clase más de Java haciendo llamadas a los métodos que exporta la interfaz.

En realidad lo que hay detrás es un actor no tipado. Akka monta un proxy en el que el interfaz será la fachada y el ‘contrato público‘ que podrá utilizar el resto del código java. Los atributos de los métodos de ese interfaz serán los mensajes que se enviarán al actor y la implementación será la que dicte el comportamiento. Por lo demás se cumple con el modelo de actores que asegurá que no habrá más de un hilo ejecutando el actor.

Todo esto, que haya un actor detrás de este interfaz, hace que tenga un comportamiento diferente al esperado en una clase java, y hay que tenerlo en mente cuando se utilizan actores tipados.

Para los ejemplos se ha utilizado una clase TypedActorDummyImp que implementa el interfaz TypedActorDummy con una serie de métodos sencillos que permitirán ver con facilidad el funcionamiento de los actores tipados.

He creado dos test, uno TypedActorDummyImpTest.java que comprueba el comportamiento en una llamada normal a un método con diferentes tipos de retorno y otro TypedActorDummyImpExceptionsTest.java para ver cual será su comportamiento si se produce una excepción.

Comportamiento según el tipo de retorno.

Un método puede devolver tres tipos de respuesta: o bien es un método que no devuelve nada (void), o devuelve un objeto, o bien devuelve un futuro de objeto.

Cuando un método devuelve no devuelve nada: void

Cuando un actor tipado el tipo de respuesta es ‘void‘, lo que está ocurriendo es que se está mandando un mensaje del tipo dispara y olvida (‘fire-forget‘). En realidad se está enviado un mensaje ‘tell‘ al actor que hay por detrás, y no se espera respuesta.

Esto hace que tenga un comportamiento un poco ‘diferente‘ del esperado y es algo que se puede comprobar en los dos ejemplos.

Test 1: Llamada normal

Comando maven
mvn -Dtest=com.logicaalternativa.examples.akka.typed.TypedActorDummyImpTest#testReturnVoidWithSleep test

En este test se levanta un actor tipado que tiene un método que devuelve void. Se simula una operación costosa con un “Thread.sleep”.

Se comprueba que no se espera a la ejecución del método, sino que se continua inmediatamente con la siguiente orden. El mensaje se ha encolado al actor y este ejecutará la implementación en segundo plano, sin ningún tipo de espera en el hilo principal.

Test 2: Cuando se produce una excepción

Comando maven
mvn -Dtest=com.logicaalternativa.examples.akka.typed.TypedActorDummyImpExceptionsTest#testRuntimeExceptionVoid test

Como consecuencia de que el mensaje es enviado al actor, ejecutándose en un segundo plano, el hilo principal no es capaz de saber si ha ocurrido un error en la ejecución. Si se produce una excepción no será recogida desde la llamada al método.

El test anterior permite hacer esta comprobación y es bastante didáctico.

Cuando un método devuelve un futuro

Test 1: Llamada normal

Comando maven
mvn -Dtest=com.logicaalternativa.examples.akka.typed.TypedActorDummyImpTest#testFutureEcho test

Cuando se llama a un método de un actor tipado que devuelve un futuro, el comportamiento sería el mismo que si se enviara un mensaje de petición y respuesta no bloqueante. Es el equivalente al envío de un mensaje con ‘Patterns.ask(…)’ de un actor no tipado.

Por lo tanto la respuesta se recogerá cuando se resuelve el futuro y no desde la llamada al método. El hilo principal continuaría su ejecución sin esperar.

Test 2: Cuando se produce una excepción

Comando maven
mvn -Dtest=com.logicaalternativa.examples.akka.typed.TypedActorDummyImpExceptionsTest#testRuntimeExceptionFuture test

Lo mismo pasaría si se produjera una excepción, sería devuelta en la resolución del futuro y no sería recogida en la llamada al método tipado. Esto entra dentro de lo lógico si pensamos que cuando se produce el error es en el momento en el que se procesa el mensaje por parte del actor.

Cuando un método devuelve un objeto

Test 1: Llamada normal

Comando maven
mvn -Dtest=com.logicaalternativa.examples.akka.typed.TypedActorDummyImpTest#testEcho test

Test 2: Cuando se produce una excepción

Comando maven
mvn -Dtest=com.logicaalternativa.examples.akka.typed.TypedActorDummyImpExceptionsTest#testRuntimeExceptionString test

Cuando se llama a un método de un actor tipado que devuelve un objeto, el comportamiento es ‘parecido‘ al esperado. Y digo ‘parecido‘ porque en realidad lo que se está haciendo es enviando el mensaje al actor y esperando la respuesta (siguiendo un patrón de petición-respuesta bloqueante)

Por lo tanto desde la llamada al método de un actor tipado hace que hilo de ejecución principal espere la respuesta (aunque por detrás se esté enviando un mensaje ejecutándose en otro ‘hilo’). Por lo tanto el comportamiento es ‘el mismo’ al acostumbrado (ver el ejemplo 1). En este caso si se produce una excepción si será recogida en la llamada al método (Ver test 2)


Como conclusión final de esta serie de posts decir que aunque el modelo de actores y Akka presentan nuevos conceptos, estos una vez aprendidos son sencillos de asimilar.

A cambio ofrece un modo elegante y sencillo de codificar aplicaciones que soporten programación paralela  que sean escalables, robustas y  de alta disponibilidad.

Espero que os sirva.

M.E.

La aventura de Civitana.org


Actualización octubre del 2014:

» Después de un verano intenso que nos ha dado tiempo a desarrollar un protocolo de voto electrónico en el que por mis tareas me he tocado definir y desarrollar en gran parte, a partir de octubre de 2014, las circunstancias  hacen que me desligue de Civitana.org, .

Aunque tengo una pequeñisima parte del ella desde ese momento paso de ser ‘cerdo’ a convertirme en ‘pollo’. Quizás más adelante, cuando las circunstancias cambien en un futuro se pueda retomar la relación laboral.»

M.E.


Han sido unos meses muy intensos y cuando por fin Civitana.org está en producción siento la necesidad de escribir esta entrada. Mucho trabajo y no pocos retos los que hemos tenido que superar.

El primer contacto

Fue a [Civitana]principios de verano pasado cuando Iván contacto conmigo para presentarme su proyecto.

Lo que me encontré fue una declaración de intenciones de proyecto ambicioso, del que todavía no somos conscientes del calado que puede llegar a tener.

Me presentó un proyecto donde la palabra “Firma” dejaría de estar desvirtuada. Pasaría a tener un valor probatorio real, tanto de integridad, como de veracidad de la misma y de verificación de cuando se realizó.  Un proyecto donde la “participación ciudadana” se vería respaldada por un documento firmado electrónicamente, cuya firma estuviera basada en estándares, para que pudiera ser fácilmente validada y que solamente con él se pudiera defender el cambio. El reto de como presentaba el concepto de identidad en Internet era algo que se adelantaba a lo que probablemente tengamos en un par de años.

Todo estaba por hacer, se partía desde cero. Me uniría al proyecto en calidad de consultor en firma electrónica gracias a la experiencia anterior en el Ministerio de Cultura. En realidad a los que formamos el equipo técnico de Civitana con Tania, Jesús y yo mismo, nos ha tocado hacer de todo y estar en todos los frentes.

El comienzo

Mientras todo se definía y entre unas cosas y otras todo se retrasó hasta medidos de octubre. La propia naturaleza y lo innovador del proyecto me hizo ser consciente que podría tener un futuro incierto.

He de reconocer que los principios fueron duros pero a la vez apasionantes. Aunque para ser sincero, esto ha sido así en todo el proceso y no sólo al principio. Cada paso ha sido un reto que hemos tenido que superar y del que por ahora siempre hemos salido airosos.

Primero había que definir la arquitectura y la tecnología. Civitana tenía que ser escalable y montada con alta disponibilidad y además muy interactiva y usable. Creo que se eligió un stack tecnológico que cumple con todo ello. Con Frontend y Backend diferenciados y escalables, solución mixta de bases de datos relacionales y NoSql, sistema de ficheros distribuido,..etc.. Perdonarme que no pueda ser más específico pero en Civitana.org hay mucho más de lo que se ve.

Finales del año pasado

Y fue cuando estuvimos en el quizás hasta ahora ha sido el momento más crítico del proyecto.

La firma no iba como nosotros queríamos que fuera.  Nos obligó a realizar una nueva implementación de la parte de firma y generación de claves desde cero con otra tecnología, y lo que fue nuestra debilidad, se ha convertido en nuestra fortaleza. Ahora tenemos firma con cualquier dispositivo que tenga un navegador moderno, sin necesidad de instalar java, plugins, drivers, aplicaciones nativas….

Sin poder entrar en detalles, de un plumazo pasamos a tener firma en PC, firma en “movilidad”, etc… Y lo mejor de una manera usable, universal, basada en estándares, y como debe ser generando las claves y la firma en el cliente, es decir, en el navegador.

Y todo con, a mi modesto entender, a años luz en facilidad de uso y universalidad de la “firma electrónica” a la que está todo el mundo acostumbrado. Como chascarrillo, siempre digo que esto nunca será valorado suficientemente,… si no es alguien que ha tenido que dar soporte de firma electrónica en una Sede Electrónica (un “pequeño” infierno y lo digo por lo he sufrido en mis propias carnes 🙂 ).

¡Ah! y todo es tecnología “by Civitana”.

Salir a producción

Nos tocaba ponernos “el gorro” de sistemas y montarlo todo en la nube, que es toda una aventura en si,… auditoria de seguridad, terminando la maquetación del diseño … en fin ultimando todo para por fin salir a producción el 15 de Mayo.

¿Y ahora? El futuro sigue incierto, ..’¿la gente tomará como suya Civitana?, ¿realmente lo verá como la herramienta que puede ser?’…. De lo que no tengo duda es todo el equipo técnico de Civitana disparamos siempre nuestro ‘mejor tiro‘.

M.E.

Configuración de entornos flexible en Spring utilizando SpEL

Introducción

En general cuando desarrollas una aplicación de cualquier tipo te enfrentas al reto de:

1) Configurar la aplicación de una manera sencilla

La configuración tiene que ser cómoda de modificar y tiene que estar centralizada (evitando que este desperdigada en multitud de ficheros de configuración las rutas, parámetros de conexión etc…)

2) Que un mismo ejecutable (jar o war en el caso de java) sirva para diferentes entornos.

Evitar tener que hacer un build para diferentes entornos (Además probablemente en un entorno corporativo no tengas acceso a las contraseñas y a las rutas de los recursos, etc.. de producción) A esto es a lo que me refiero con externalizable.

Spring es una poderosa y elegante herramienta que permite configurar una aplicación y establecer las dependencias entre sus clases a través de anotaciones o mediante archivos xml.

Pero esta potencia también puede llevar al peligro de que si no somos cuidadosos tengamos los parámetros de conexión, contraseñas, URL y rutas desperdigadas en varios archivos.

Para esto Spring ofrece herramientas que permiten cargar propiedades y valores de archivos ‘.properties‘ y además estos archivos pueden encontrase fuera del jar o del war e incluso pueden estar cifrados. Con esto se soluciona la centralización y la externalización.

El problema

Hecha la introducción paso a explicar el problema: Había que configurar una aplicación web en Spring en diferentes entornos en una misma máquina (un entorno en un Jetty y otro en un Tomcat), por lo que había que externalizar la configuración y además al estar en la misma máquina no servía que la ruta al fichero de configuración fuera fija (de estilo ‘/home/usuario/aplicacion.properties‘)

La solución

Ha sido utilizar el bean ‘PropertyPlaceholderConfigurer‘ de Spring y utilizar SpEL (Spring Expression Language) de esta forma:

01
<?xml version="1.0" encoding="UTF-8"?>
02
<beans xmlns="http://www.springframework.org/schema/beans"
03
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
05
 >
06
...
07
 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
08
  <property name="locations" value="#{systemProperties['aplicacion.config'] != null ? 'file:' + systemProperties['aplicacion.config'] :'classpath:'}application.properties"/>
09
 </bean>
10
 ...
11
 </beans>

Código 01. Configuración xml de ‘propertyConfigurer’

La clave está en la línea 8. Si está definida la propiedad del sistema ‘aplicacion.config‘ buscará en el sistema de ficheros, el archivo de configuración ‘aplicacion.properties‘ en la dirección que indica su valor. Si no, busca el ‘aplication.properties‘ en el classpath (es decir dentro del war), por lo que este sería el archivo de configuración de la aplicación por defecto.

Un ejemplo del contenido de ‘aplicacion.properties‘ podría ser

1
...
2
aplicacion.config.pathfiles=/home/miguel/aplicacion/tmp
3
...

Código 02. Ejemplo de contenido de aplicacion.properties

Y la manera de usarlo dentro de la configuración xml de Spring sería:

01
<?xml version="1.0" encoding="UTF-8"?>
02
<beans xmlns="http://www.springframework.org/schema/beans"
03
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
05
 >
06
...
07
 <bean id="utilFichero" class="com.logicaalternativa.ejemplo.UtilFicheroImp"> 
08
  <property name="directorio" value="${aplicacion.config.pathfiles}"/>
09
 </bean>
10
 ...
11
 </beans>

Código 03. Ejemplo de como se utilizan los valores definidos en el archivo de configuración

Ya sólo me queda indicar como se define esa propiedad. En el Tomcat un buen sitio es el ‘catalina.properties de su directorio ‘config‘. Se definiría así:

1
...
2
aplicacion.config=/home/miguel/config-aplicacion-tomcat/
3
...

Código 04. Configurando el Tomcat

O directamente definiendo la propiedad al arrancar la máquina virtual. Por ejemplo si tu proyecto tiene configurado el plugin,  arrancando el jetty embebido de mvn de la siguiente manera:

1
mvn -Daplicacion.config=/home/miguel/config-aplicacion-jetty/ jetty:run

Código 05. Ejemplo al arrancar el jetty de mvn

En los ejemplos en los dos directorios ‘/home/miguel/config−aplicacion−jetty/‘ y ‘/home/miguel/config−aplicacion−tomcat/‘ se encontrarían sendos archivos ‘aplicacion.properties‘ cada uno configurados con los valores para cada entorno.

Espero que os sirva.

M.E.