domingo, diciembre 30, 2007

Feliz año nuevo y ya son cinco años bloggeando

domingo, diciembre 30, 2007 por Martín

Bueno, quizás alguno haya notado que no he escrito nada esta última semana. Esto se debe a que ahora mismo estoy en España, de vacaciones, y escribiendo esta entrada con una conexión de prestado.

Hemos aprovechado estos días para visitar a la familia y aunque esto ya se está acabando y pronto, pero que muy pronto (sniff), estaré ya de vuelta por Dublin, pues quería aprovechar la ocasión para felicitaros a todos los que os pasáis de vez en cuando por aquí un feliz año 2008.

Y otra cosa, es que parece que debo estar de cumpleaños. Allá por finales del 2002 empezaba a bloggear. Es una pena porque aunque cuando el año pasado comentaba que era el cuarto aniversario todavía estaba disponible mi viejo blog en blog-city.com pero ahora lo han borrado ya. Lo más viejo que he encontrado es lo que se puede ver en el historico de archivo.org que es de Abril del 2003.

Que tiempos eran aquellos. El concepto de blog apenas existía y creo que eramos unos cuantos "frikis" los que teníamos la desvergüenza de escribir a pecho descubierto en la red de redes. Claro, ahora lees las entradas y te partes de risa: que si patentes en .NET, que si nos recomiendan escribir tests unitarios, que si las nuevas características de C# y si Java las debe adoptar, en fin. Cuantas cositas que al final, realmente, aunque en el momento nos puedan parecer importantes, pues mirando hacia tras te das cuenta de que son un poco tonterías, que todo se ha pasado ya y que realmente lo importante es pasar un año más con tu familia, amigos y las personas que quieres. Siempre hablamos de que la tecnología avanza rapidísimo, pero la verdad es que los años pasan todavía más rápido :-)

Pues eso, que ¡feliz año!

martes, diciembre 18, 2007

Reporting en Java, como hemos cambiado...

martes, diciembre 18, 2007 por Martín

Comentaba hace unos días que andaba a la busca que de motores de generación de informes en Java porque los clientes empiezan a preguntar por algo así. La verdad es que desde que había dejado España no había tenido que mirar más este tipo de herramientas. Hoy, acabando ya la revisión me han venido a mente una serie de recuerdos de esos que te hacen pensar lo viejo que vas ya, porque vaya que no han cambiado las cosas.

Mi primer contacto con la generación de informes en Java debió ser allá por el 1999. Casi nada, oiga. Necesitábamos un framework para generar informes de manera sencilla y ... no había nada. Pero nada de nada. Recuerdo que el imprimir un informe utilizando AWT era un infierno. Una miserable página te ocupaba unos 50Mb de memoria (que en aquella época ya era algo), la CPU se disparaba, pantallas en blanco (que Swing no era lo que es), etc. Al final, como nuestras impresoras soportaban PCL5 lo que hice fue crear una especie de printer spool en Java contra el que se programaba mediante una API de alto nivel pero que en realidad creaba informes que se generaban en PCL5 y se enviaban a la impresora. Vaya, eso sí que volaba. Los informes eran ligerísimos y se imprimían como balas, las páginas que fuesen.

Durante los años siguientes, ya en otro lugar, siempre tuve que andar dando vueltas con los informes. Los primeros años, allá por el 2001 y 2002, la verdad es que seguía sin haber nada de nada. O al menos nada utilizable. No quedaba otra que utilizar alguna herramienta propietaria que siempre iba un poco más adelante, pero como nunca había mucho dinero te las tenías que ahorrar con versiones viejas que no tenían todo lo que querías.

Ya hace tres o cuatro años empezaron a aparecer cosas interesantes. Teníamos Jasper Reports o JFreeReport, y alguno más por ahí que ya se ha muerto. En fin, que estaban muy bien, pero que diseñar, lo que se dice diseñar, pues que no había mucha herramienta. Estaba el iReport, que no se parecía en nada a lo que encontráis hoy en la web. Era cutre y un infierno, pero después de mucho pelear pues hasta conseguías que funcionaba.

Y ahora, hoy en día, que maravilla. Han pasado ocho años y por fin se puede ser medianamente productivo a la hora de hablar de informes. Ya era hora, por cierto. Ayer estuve jugando un poco con el Report Designer y con su reporting engine (otrora JFreeReport) y es que eso ya no es lo que era. Con su wizard, conectándote a tu base de datos y escogiendo diferentes plantillas, definiendo todas las agrupaciones, el formato, etc. y al final que te genera el informe el sólito y que lo puedes publicar a tu portal web de inmediato. Buf.

Y hoy le tocó a BIRT y como ha cambiado también. Me acuerdo hace un par de años que BIRT estaba cogiendo muchísima fama y en la EclipseCon tuve la oportunidad de hablar con gente que lo estaba utilizando, y bueno, estaba bien, pero no servía para la web y era bastante complicado de utilizar. Pero hoy, en 10 minutos tenía una aplicación web y varios informes contra mi base de datos funcionando. El editor es espectacular, de lo mejorcito que he visto, super sencillo de utilizar. La integración con WTP es perfecta, vas creando el informe y lo puedes desplegar y probar al momento. Una maravilla vamos.

En fin, que como han cambiado las cosas. Parece que fue ayer. Ahí sentado en nuestra oficinita con Jesús y Miguel peleando con los comandos de PCL5 y alucinando con lo rápido que podíamos imprimir. Sólo han pasado ocho años. No estoy seguro de si eso es bueno o malo :-)

domingo, diciembre 16, 2007

Lo nuevo de Amazon: SimpleDB

domingo, diciembre 16, 2007 por Martín

Parece que Amazon acaba de lanzar una limited beta de su nuevo servicio web SimpleDB. A estas alturas (el lanzamiento fue el Viernes) ya hay un montón de información sobre sus características técnicas. Una de las más llamativas es que el servicio web se ejecuta sobre erlang.

El nuevo servicio web propone un modelo muy simple basado en tener un dominio de datos que almacenará items los cuáles tendrán diferentes atributos en forma de clave valor. Sobre ese dominio se pueden ejecutar diferentes operaciones:
  • CREATE: para cear una nueva base de datos.
  • GET, PUT, DELETE: para obtener, crear o actualizar y eliminar items y propiedades en una base de datos.
  • QUERY: para hacer consulta de datos. Las consultas están limitadas a cinco segundos.

El precio depende de diferentes factores como la cantidad de CPU utilizada al realizar las operaciones, el ancho de banda consumido tanto in como out, y el espacio en disco ocupado por la base de datos. Pero vamos anda en torno al 0.14$ por hora, 0.11$/0.18$ al mes por Gb. in/out y 1.50$ al mes por Gb. de almacenamiento.

Sobre todo esto y más detalles podéis consultar la web de SimpleDB desde la que tienen también una guía para iniciarse y y la guía de desarrolladores. De todas las opiniones que hay ya ahora mismo en la blogosfera sobre el servicio, me he quedado con las que me resultan particularmente interesantes y que resumo a continuación.

Charles H. Ying apunta varias consideraciones importantes en su blog como que la latencia en la sincronización de datos entre diferentes nodos puede ser grande (+1 sec.), que las queries sobre los objetos son lexicográficas (ej. 4 > 35 pero 04 < 35), o que el API no soporta búsquedas de texto. En High-Scalability no han tardado en hacerse eco de la noticia y ya publican una amplia lista de pros y contras. Parece que la mayor parte de los contras se centran en que el servicio es caro para lo que ofrece, en los posibles problemas de consistencia y latencia, la falta de soporte para algunos lenguajes, y resumiendo en que no te ofrece mucho lo que una base de datos te puede ofrecer ahora mismo; los pros se centran sobre todo en el aspecto "hosted", es decir en que no se necesita un administrador de base de datos, en que no necesitas comprar la base de datos ni hardware, en su soporte de replicación y en que puede ser algo muy interesante para startups.

Sriran Krishnan hace una revisión técnica bastante completa donde muestra un ejemplo de petición/respuesta utilizando el API REST que ofrece SimpleDB y se centra también en el problema de la latencia de las actualizaciones y que los datos no se repliquen instantáneamente en todos los nodos. Este punto es interesante, pero en mi opinión no refleja otra cosa sino que este servicio está enfocado hacia cierto tipo de aplicaciones y no debe utilizarse como una silver bullet. Por poner un ejemplo, realmente en un portal de opiniones sobre viajes, restaurantes, hoteles, lo que quieras, la consistencia de los datos en un márgen de unos segundos no es precisamente algo muy importante.

Don MacAskill apunta también algo bastante importante y es que este servicio puede que sea apto sólo para aquellos que ya estén utilizando Amazon EC2. La razón fundamental es la latencia. A no ser que nuestros servidores estén cerca de los de Amazon, sí decidimos utilizar SimpleDB tendremos que sumar a cada consulta el tiempo de latencia en obtener dichos datos, lo que dependiendo del número de consultas puede ser un problema importante.

viernes, diciembre 14, 2007

Antipatrones de gestión de proyectos

viernes, diciembre 14, 2007 por Martín

Pero que bueno el post de Michael Nygard sobre Budgetecture y
todos sus primos. ¿Quién no se ha encontrado alguna vez con ellos?

Budgetecture es un juego de palabras con budget (presupuesto) y architecture (arqhitectura). La arquitectura, o si queréis la gestión del proyecto, es una continua negociación. Requiere realmente autoridad y habilidad para negociar una solución correcta, no sólo con tus desarrolladores sino también con las personas que manejan el presupuesto. Lo malo es que los ingenieros tendemos a ceder fácilmente. Yo creo que es algo que nos ha pasado, o nos pasa a todos. Al fin y al cabo, somos ingenieros, ¿no? Nos gusta todo esto, la programación, los sistemas, el cacharrear y todas estas cosas. Nos gustan los retos. Así que cuando viene el dueño y nos dice si no podríamos utilizar la tecnología Y en lugar de la X, que resulta que es muy cara, tendemos a decir cosas como "buenoooo siiii, si poneemos esto por aquí y esto por allá... igual funciona". Y lo peor es que es cierto, igual funciona, pero lo más probable es que no y en caso de que funcione seguramente lo hará peor y nos dará muchos más dolores de cabeza.

Otro patrón que comenta y que es muy habitual es el de los favores en las agendas. Y este si que le tiene que sonar a todos. Estás desarrollando contra requisitos imposibles, sabes que no llegas y se lo dices a tu jefe. Y tu jefe como es tan bueno te hace caso y te deja terminar dos meses después.... a cambio de añadir tres funcionalidades nuevas que otro cliente ha pedido. Simplemente genial. Ya sabes, si no te gusta una taza de caldo, pues te damos dos ;) ¿A alguien le suena?

Y el último, también genial y probablemente hiperconocido es la falacia del capital. Básicamente se simplifica a que hemos conseguido convencer al jefe para que nos compre nuestro nuevo y caro juguete: WebSphere, Oracle, WebLogic, SQLServer, lo que sea. Y ahora lo tendremos que usar, y vaya si lo tendremos que usar. Lo tendremos que usar para todo proyecto que salga de la compañía, porque como se nos ocurra hacer un diseño después de haber comprado ese producto en el que no aparezca su nombre, ya nos podemos preparar. "¿Qué no estás usando WebSphere para ese programa de mantenimiento de clientes? Ya lo puedes poner ahora mismo que hemos pagado mucho dinero por él." Y ya podemos ir pensando en como alojar todas las aplicaciones de la empresa en ese producto, porque con lo caro que es nadie se va a creer que una licencia sólo se puede utilizar para una o dos cosillas a la vez que si no la cosa ya no da para más :-)

No sé si os han pasado cosillas como estas en vuestras empresas, ¿alguién se anima a comentar sus experiencias?

jueves, diciembre 13, 2007

Información sobre reporting engines en castellano

jueves, diciembre 13, 2007 por Martín

Argh... los clientes empiezan a pedir herramientas de reporting para construir sus informes. Menos mal que el fenomenal blog de Stratebi siempre está ahí para contarme todo lo que me pierdo en el mundo del Business Intelligence.

Hace una semana han publicado un tutorial de JasperIntelligence de 40 páginas que me ha venido de perlas para al menos conocer esta herramienta.

Y eso por no hablar de la comparativa que publicaron en Octubre de los reporting engines de Jasper Reports, BIRT y Pentaho. Indispensable.

Rendimiento en colleciones de datos en Java

jueves, diciembre 13, 2007 por Martín

Hubo una época en el rendimiento de las colecciones de datos, es decir java.util.Collections, era realmente penoso. Blogs, forums y portales de programación predicaban sobre la necesidad de optimizar su funcionamiento y muchos se veían obligados a migrar a terceras librerías para obtener clases que a la hora de iterar no fuesen pasando por todos los objetos null de una lista, o que no doblasen el tamaño cada vez que te pasabas del tamaño de la colección y todas estas cosas.

He estado haciendo una pequeña evaluación de estas librerías para confirmar lo que ya me suponia. Esa época de optimización necesaria ya ha pasado a la historia. Hay que reconocer que el rendimiento de las colecciones de datos tanto en el JDK 5 como en el JDK 6 es ahora muchísimo mejor, y las librerías que en otrora tenían algo que decir han pasado un poco desuso. La verdad, no creo que cuente ningún secreto, pero bueno es uno de estos tipos de test que tienes que hacer, al menos para asegurarte de que no te estas perdiendo algo bueno. Lo cierto es que desde hace varios años ya no se oye a ven los post de los creadores de estas librerías en los foros técnicos, lo que te sugiere que ellos mismos sabes que su trabajo ya ha finalizado.

Una de las librerías que he mirado es GNU Trove pero la verdad es que es no pasé ni siquiera de las primeras pruebas. El problema de esta librería es que no implementa las interfaces estándar como java.util.Map o java.util.Set y te fuerza a atarte a sus propias estructuras de datos. Así que nada, descartada (además cuando evalué oval, que te permite utilizar diferentes implementaciones de colecciones de datos ya vi que el rendimiento no era mejor que el de las clases del JDK).

La siguiente en evaluar fue Javolution que tiene una serie de colecciones de datos. Esa librería es interesante. En algunos tests, como por ejemplo al utilizar listas, el rendimiento puede llegar a ser unas 10 veces mayor que con las clases del JDK, mientras que en otros tests el rendimiento es claramente peor, como por ejemplo usando mapas. El problema de esta librería es que está orientada a pequeños dispositivos en el que operaciones como crear y liberar memoria son caras, y por lo tanto sigue un modelo de programación un poco peculiar. Por ejemplo, hace cosas como crear un pool de entradas que reutiliza para las diferentes colecciones de datos, así si tenemos un mapa en el que estamos continuamente colocando y eliminando objetos en lugar de crear nuevas entradas, se reutilizan las que hay en el pool. Sin duda inteligente, pero este tipo de cosas pueden ser bastante perjudiciales dependiendo de como funcione la aplicación, y en mi opinión sería un error el meterse a utilizar librerías que tienen ese funcionamiento tan peculiar.

Por último está Commons Collections. El rendimiento de esta librería es peor que el del JDK, y además no soporta genéricos lo que es un problema adicional. Aún así, la verdad es que el punto fuerte de esta librería ya no es el rendimiento si no más bien la cantidad de diferentes algoritmos y colecciones que tiene implementados, así que puede ser realmente útil para aprovechar cosas que no haya en el JDK.

En fin, mi conclusión es que ahora mismo no tiene ningún sentido ya el mirar como reemplazar colecciones de datos que vienen en el JDK. Eso era una tarea útil hace
quizás hace cinco años, pero ya no lo es. Sin embargo, hay que agradecerle a toda esta gente que allá por el 2000 ya se preocuparon de comenzar a ponerle las pilas a
los desarrolladores del JDK para que mejoraran el rendimiento. Si no hubiese gente quejándose y desarrollando implementaciones mejores probablemente no tendríamos
ahora unas colecciones de datos decentes.

lunes, diciembre 10, 2007

Cuidado con los nombres de clases graciosos

lunes, diciembre 10, 2007 por Martín

¿Qué opinaríais si estuviéseis depurando una librería de un proveedor de terceros que estáis evaluando comprar y de pronto descubriéseis que algunas de las clases de su servidor comienzan con el prefijo de .... ACME !!? (ojo, hay empresas que se llaman así, pero este no es el caso)

Jejeje, parece una tontería, pero imaginaros mi cara cuando, estando ya muy escamado por la calidad de su implementación, me encuentro con que el depurador entra en clases como AcmeHashTable. A alguno que estaba a mi lado le iba mal. Claro, vete a saber, en cualquier momento va y te explota el servidor de aplicaciones ;)


En fin, que supongo que no está mal el limpiar un poco las librerías, sobre todo cuando se las vas a pasar a un cliente potencial. Lección que aprendo para el futuro, por si estoy del lado proveedor.

domingo, diciembre 09, 2007

El algoritmo de Nagle

domingo, diciembre 09, 2007 por Martín

Uno de los temas recurrentes y sobre los que siempre hay que pensar en el entorno en el que me encuentro es el algoritmo de Nagle. Este algoritmo es una optimización de TCP/IP para evitar su la gestión de las redes. La idea es que si un sistema envía muchos paquetes pequeños (e.g. 1 byte) continuamente se está desperdiciando mucho espacio en el paquete TCP/IP y por lo tanto se puede congestionar mucho una red.

Para ello, Nagle, ideó un algoritmo mediante el cual sólo un paquete pequeño puede viajar por la red sin que se haya recibido un ACK. Esto significa que hasta que no se reciba un ACK se estarán acumulando paquetes dentro de un buffer. Cuando el ACK se recibe se envía de nuevo un paquete TCP/IP pero esta vez con muchos más datos ya que contendrá esos pequeños mensajes que se habían estado acumulando.

La idea es muy buena, pero a parte de los problemas que tiene este algoritmo con otra optimización llamada delayed ACKs y que se desarrolló en la misma época (es lo que tienen los diferentes grupos de trabajo sin comunicación entre ellos) resulta que este algoritmo te obliga irremediablemente a esperar por los ACKs.

Ahora supongamos que estamos haciendo streaming de datos en tiempo real. Imaginémonos que no es vital el tener la seguridad de que estos datos lleguen a su destino (es decir, no necesitamos ACK), pero sí que es vital el enviar estos datos lo más rápido que sea posible. Ejemplos de este tipo de escenarios pueden ser streaming de datos médicos o trading en mercados financieros en el que diferencias en milisegundos pueden suponer el ganar o perder mucho dinero.

Volviendo al ejemplo, imaginémonos que por cosas de la vida nuestro data center está en Madrid y nuestro cliente en Chicago. Esto, si le hacemos caso al visualizador de latencia de Akamai son unos 330 milisegundos (asumo que en round-trip). Eso son 165 milisegundos ir y otros tantos volver. Una cuenta fácil es que con el algoritmo de Nagle seremos capaces de enviar tres mensajes mientras que si en el nos vamos a los 6 mensajes por segundo. Si dentro de cada mensaje TCP/IP puedo enviar cotizaciones digamos 8 cotizaciones pues pasaría de poder mostrar unas 24 cotizaciones por segundo a unas 48. Una aumento considerable.

¿Cómo puedo deshabilitar el algoritmo de Nagle? Fácil, utilizando el atributo TCP_NODELAY presente en la mayoría de lenguajes. Los que utilizamos Java tenemos buenas y malas noticias. La mala es que por defecto no hay manera de deshabilitarlo a no ser que vayamos a gestionar nosotros mismos la comunicación de sockets (es decir, que utilizando URL.openConnection() nada de nada). La buena es que excelentes librerías Open Source como Apache Commons HTTPClient o Apache Mina nos permiten hacer esto y muchísimas más cosas y son siempre una mucho mejor elección que utilizar las librerías de Sun.

Vaya post me ha salido para un Domingo :) Pero bueno, es una de estas cosas que te interesa apuntar así que la he dejado por aquí para futura referencia y por si a alguien le es útil. Espero no haber aburrido, al menos mucho, a nadie :)

miércoles, diciembre 05, 2007

Algo de humor: MashUp Camp, Dublin

miércoles, diciembre 05, 2007 por Martín

Un poquillo de humor nunca viene mal. Hace un mes se celebró en Dublin un MashUp Camp. Además creo que era el primero de Europa, y bueno hubo gente de Yahoo, de SalesForce, IBM, Reuters y todas estas cosas.

El caso es que se les ocurrió hacer un video saliendo a la calle y preguntándole a la gente si sabía lo que era un "MashUp". Me ha hecho mucha gracia porque representa Dublin por la noche en estado puro.





Tenéis el video en la Yahoo Developers Network.

lunes, diciembre 03, 2007

10 formas de reducir la contención por bloqueos

lunes, diciembre 03, 2007 por Martín

En Thinking Paralell, Michael Suess publica un excelente artículo en el que comenta 10 formas para reducir la contención por bloqueos en programas concurrentes.

Me permito castellanizarlos aquí:

  1. Proteger sólo los datos y no todo el código.

  2. Evitar cálculos complejos y largos dentro de locks.

  3. Evitar el utilizar un único lock para todos los elementos.

  4. Utilizar las operaciones atómicas disponibles en numerosos lenguajes.

  5. Utilizar estructuras de datos ya sincronizadas (y si es posible lock-free).

  6. Utilizar read-write locks cuando sea posible. Muchos lenguajes disponen de este tipo de bloqueos.

  7. Utilizar datos de sólo lectura siempre que sea posible.

  8. Evitar pools de objetos.

  9. Utilizar variables locales o aprovechar el almacenamiento local en hilos.

  10. Evitar puntos calientes (e.g. variables compartidas que se llaman mucho).

  11. Bonus: Utilizar un sistema de memoria transaccional.



La programación concurrente es compleja, de eso no hay duda. Algunos dirían que hasta da miedo :-) Pero bueno, todavía daba mucho más miedo hace años cuando en lenguajes como Java variables como volatile funcionaban como querían. Lo peor de la concurrencia en Java es que simplemente empezó a ser decente demasiado tarde, con el paquete java.util.concurrent de Java 5. ¿Por qué es tarde? Pues porque ahora mismo coges a muchos programadores y les preguntas el significado de las palabras synchronized, volatile o qué es un ThreadLocal y muchos no lo van a saber, pues cual puede ser el resultado de preguntar que es un ReadWriteLock o un AtomicInteger.

¿Culpa de los desarrolladores? No creo. Si el 90% de los libros sobre programación básica en Java no hablan de estas cosas y se quedan en Thread.start() y Thread.run() difícilmente vas a concienciar de la dificultad de la programación concurrente. (Hago aquí un inciso porque yo fuí de los de programación concurrente en C, pero supongo que ahora mismo se estará dando en Java así que quizás la situación no esté tan mal en este lenguaje).

De todos modos, yo me quedo con lo que comenta Brian Goetz, autor del excelente libro Java Concurrenty in Practice en los comentarios a la entrada, y es que estas medidas deberían aplicarse con mucho cuidado y únicamente cuando se compruebe que realmente existe un cuello de botella debido al uso indebido de bloqueos. El intentar aplicar estas reglas de buenas a primeras sería adentrarse dentro del mundo de la optimización prematura (que es siempre algo malo, pero que hay que diferenciar del diseño en busca de rendimiento como comentaba hace unos días).

Me iba a enrollar ahora comentando algunas de las entradas, pero es que tampoco creo que valga mucho la pena. El que se lea el libro de Brian Goetz, es que ya va a saber todo lo que necesita saber. Y aunque el libro está basado en Java, creo que es una buena lectura en general independientemente del lenguaje. Eso sí, mejor os dejo con una captura de pantalla que hice hace unos meses y de la que iba a hablar en un post a ver que os parece:



¿Qué representa? Pues es nada menos que un servidor WebLogic que de repente se va a un 100% de uso de la CPU como quien no quiere la cosa. ¿Qué malvado código puede crear ese efecto? ¿Quizás un EJB que está procesando todos nuestros proveedores? ¿Un malvado timer que ha saltado y está lanzando un proceso batch de esos qeu todos tememos? mmm Pues no. Un simple put() en un HashMap puede hacer eso, especialmente si tienes la mala suerte de que el HashMap esté compartido (ejem, malo malo) y dos threads se les ocurra hacer el put() al mismo tiempo (efecto conocido en HashMap), ya que en ese caso es muy probable que entren en un bucle infinito intentando insertar el elemento, que es justo lo que podéis ver en la imagen y que era exactamente lo que se estaba comiendo toda la CPU de un pedazo servidor.

Imaginaros que esto pase en producción. En fin, en este caso la solución es utilizar en su lugar un ConcurrentHashMap que garantiza un cierto grado de concurrencia (o también no compartir el HashMap :-) ), pero supongo que os dará una idea de lo peligrosas que pueden ser cosas que en un principio pueden parecer realmente inocentes.

Bueno, mientras tanto, yo todavía estoy con ganas de leer algo que leí en en el blog de Ferrán hace unos meses y que me dio mucha envidia.