Diego's profileZonaDiegumPhotosBlogListsMore Tools Help

Blog


    June 27

    Cuando un Mal Manejo de Excepciones Impacta en la Experiencia de Usuario

    boaerror
    Bank of America en calzoncillos

     El usuario ya se apioló de  que usan Java sobre IBM Websphere, que se quedan cortina de memoria, no escalan, etc. Un potencial hacker, al conocer la infraestructura en la que corre, si de paso conoce vulnerabilidades de la misma puede explotarlas en detrimento del banco y/o de sus clientes. Y eventualmente, además, en su propio beneficio.

    Ya había hablado de esto allá lejos por Septiembre de... 2005!! Ver Haciendo lugar a la Excepción.

    December 18

    Computación y Medio Ambiente: Journal 18 Recién Salido del Horno

    Journal 18 en Computación Verde El Journal que acabamos de terminar  se ocupa de "Computación Sustentable". En la medida en que la computación se hace más y más omnipresente, el consumo de energía derivado crece sin techo más allá del claro llamado a reducir el consumo y revertir el llamado "efecto invernadero". Al mismo tiempo, o quizás como consecuencia de, el costo de la energía se está elevando -derivado de medidas regulatorias en la medida en que recursos naturales no renovables se van haciendo más difíciles de obtener- lo que está manteniendo a los líderes del área de TI ocupados en maximizar la eficiencia, particularmente en un contexto de recortes debido a la crisis financiera internacional

    Fue un honor para mí tener a Lewis Curtis, Principal Architect del equipo de Arquitectura de Plataforma de Microsoft, como experto en la materia en este tópico y a la vez co-editor en jefe por este número. En el primer artículo (página 2), Lewis ofrece un enfoque holístico a arquitecturas más verdes, a la vez que nos ayudó a subdividir este tema en cinco perspectivas:

    • Física. El proyecto de investigación Genome, descripto en "Red de Sensores Inalámbrica para Monitoreo de Datacenters" (página 28), usa información de distribución de calor provista por una red de sensores inalámbricos para optimizar el diseño del datacenter de manera de evitar congelamiento innecesario de todo el lugar físico (cuando quizás el calor máximo se concentra sólo en algunos pocos lugares)
    • Plataforma Operativa. Los recursos de hardware se reservan frecuentemente en base a un escenario del peor caso cuya ocurrencia es esporádica. Como resultado, granjas completas pueden estar subutilizadas en un 90%. El artículo de Mark Pohto sobre un caso de estudio ocurrido en Microsoft TI (MSIT), consolidando servidores SQL Server (página 35) destaca virtualización de entornos y otras tácticas de consolidación
    • Inteligencia Sustentable. El Perfil de Uso de Energía (Energy Usage Profile o EUP) es una herramienta escencial para medir el consumo de energía en varios dominios como hardware, sistemas operativos, usuarios y aplicaciones; tal como el "arquitecto llegado del futuro" lo cuenta en el articulo de Steve Stefanovich y otros (página 24)
    • Desarrollo de Aplicaciones. Los arquitectos de soluciones también tienen una oportunidad acá, según apuntan Dan Rogers y Ulrich Homann en su artículo "Patrones de Aplicación para IT Verde" (página 16). La discusión acerca de la computación verde tiende actualmente a enfocarse en la plataforma, el hard y los datacenters. Sin embargo, ineficiencias de aplicación tales como algoritmos no optimizados o el uso incorrecto de recursos compartidos causando contención son originadores de un mayor tiempo de uso de CPU y, por lo tanto, de consumo energético
    • La Nube (The Cloud). En su artículo sobre un modelo de madurez de virtualización (página 9), Kevin Francis y Peter Richardson explican cómo el consumo de energía tiene chances de ser notoriamente reducido en la medida en que los proveedores de SaaS puedan hacer un uso eficiente de recursos compartidos (servidores, almacenamiento, mecanismos de enfriamiento y demás)

    En los tiempos que vienen, la computación sustentable va a ser un desafío clave para las empresas que va a presentar una oportunidad para los arquitectos de software para mostrar y demostra su liderazgo. Es un excelente momento para los que jugamos el rol de arquitecto. A la vez, celebrando el relanzamiento del programa Architect MVP (Most Valuable Professional, o Profesional Más Valioso), entrevistamos a Udi Dahan (Architect MVP por cuarto año ya) en la sección Perfil de Arquitecto (página 22)

    Esperamos que disfruten estos artículos en computación sustentable en los que hemos volcado mucho esfuerzo. Invitamos a todos a visitar el portal de Microsoft de Preservación del Medio Ambiente (Microsoft Environmental Sustainability) en http://www.microsoft.com/environment y, como siempre, pueden hacernos llegar sus comentarios a editors@architecturejournal.net

     

    Diego Dagum
    Editor en Jefe

    November 09

    PDC 2008. Architect's Cut

     Aunque, excepto algunas,  casi todas las sesiones del PDC 2008 están disponibles tanto online como offline (previo download, claro), uno puede sentir esa amarga frustración derivada de la abrumadora cantidad de las mismas

    Preguntas típicas que me hago yo mismo en esas situaciones emocionalmente encontradas son "Qué repositorio de info! Tendré tiempo de ver y posteriormente asimilar esta data!? Qué mirar primero? Qué si agarro alguna sesión que requiere ver otra antes, de modo de adquirir cierta base? Habrá alguna sesión que pudiera descartar sin sentirme culpable?"... y una larga lista de etcs

    Por suerte el equipo detrás del Microsoft Architecture Center (el Equipo de Arquitectura de Microsoft) está acá para ayudar: recorrimos la lista entera de sesiones, clasificandolas según complejidad, tópico abordado, relevancia en términos de arquitectura, etc, y extragimos una lista de unas 45 sesiones (la lista completa triplicaba o cuadruplicaba esto) que estamos actualmente exponiendo, pero en una forma gradual

     

    PDCforArcs

     

    Para estos días estamos exponiendo las que que consideramos "watchme.1st":

    • Guías de Diseño de Frameworks
    • Performance
    • Escalabilidad
    • Cloud Computing y Azure
    • El Modelo de Modelado "Oslo" (valga la redundancia smile_regular)
    • Lenguages Dinámicos
    • Caché Distribuido
    • Concurrencia y Paralelismo

     

     

    Vas a encontrar en estos días un video roller justo en la home page donde podrás seleccionar las sesiones de tu interés, click allí y, voilà!: el espectáculo comienza cuando Ud llega. No es necesario loguearse, nada

    Por supuesto, podés maximizar la ventana de video (me imagino que es lo que vas a hacer) gracias a la flamante tecnología Silverlight 2, o eventualmente visitar el sitio huesped (Channel 9) y descargar el powerpoint desde allí o, finalmente, una mezcla de todo

    October 27

    Guía de Arquitectura de Aplicación v2.0 - Beta 1 Liberada Recién

    PnP Application Architecture Guidance Mejor que  prometer cosas es ofrecer algunas realidades y esto es algo real

    Después del auspicioso éxito que la Guía de Arquitectura de Aplicación (versión 1.0) original había tenido, hubo una serie de libros en aspectos de sintonía fina tales como seguridad, rendimiento, escalabilidad, aspectos internos a los clientes inteligentes (smart client), aplicaciones web y otros

    Pero todo eso pasó entre el 2002 y el 2004 durante las oleadas de .NET 1.0 y 1.1. Y parte del feedback recibido fue posteriormente usado durante las etapas de maduración de .NET 2.0 sin embargo...

    Mientras que las mejores prácticas fueron saliendo de la agenda del arquitecto para aterrizar inherentemente en la plataforma de desarrollo (algo conocido como fase de comoditización), los arquitectos empezaban a quedarse con un sabor amargo en sus gargantas. Había muerto la Arquitectura con mayúsculas?

    La pregunta emergía una y otra vez

    MSDN Architecture Forums
    Foro de Arquitectura MSDN, tópico: va a pasar algo con la Guía de Diseño de Aplicaciones y Servicios?

    Hasta que finalmente el arquitecto de Patterns and Practices J.D. Meier tomó la posta y puso al motor de nuevo en marcha con su ahora legendario post "patterns & practices App Arch Guide 2.0 Project". J.D. comenzaba disculpándose en cierto modo: "It's long overdo..." ("es muy exagerado...")

    J.D. Meier's Blog

    Hoy, coincidiendo con la inauguración de sesiones en el PDC (la Conferencia de Desarrollo Profesional de Microsoft) en Los Angeles, la Beta 1 del proyecto fue liberada

    Application Architecture Guide 2.0 BETA 1

    Estuve echando un vistazo (en la medida en que me hago tiempo, soy a la vez contribuyente de este proyecto), y puedo garantizar al lector de esta guía que no es sólo una migración de .NET 1.0/1.1 a .NET 3.5 SP1 sino una redefinición completa de lo que Arquitectura de Aplicación significa hoy. Incluso más allá de la plataforma .NET, por qué no

    Este importante punto podría ser confirmado con sólo revisar cómo la información está organizada a lo largo del libro

    Information Architecture

    Tipos de aplicación, Estilos de Arquitectura, aspectos cruzados y un marco general de características que cualquier arquitectura debe tener en cuenta (más allá del tipo de aplicación soportado o del estilo que se siga como plano general)

    J.D. estimula al lector a descargar y aplicar estos recursos como si fuera la versión final de la guía, de manera de proveer feedback sea a través del motor de discusión de Codeplex (ver pestañas "Discussions" y "Issue Tracker"), o contando tus experiencias de dar vuelta el partido al haber usado esta guía a MyStory@Microsoft.com

    Es apenas la Beta 1 pero está sin dudas tomando forma. Sé parte del proyecto y ayudá a J.D. a hacer que la espera valga la pena! Open-mouthed

    September 30

    UML, Al Fin en Visual Studio (versión 2010, "Rosario")

    smile_omg   smile_secret   smile_party

    Semana Visual Studio 2010 en Channel9
    Semana Visual Studio 2010 en Channel9

     

    Camino a
    Camino a "Rosario"


    Peter Provost cuenta para nosotros (arquitectos) que viene en Visual Studio 2010
    Peter Provost cuenta para nosotros (arquitectos) que viene en Visual Studio 2010

    August 27

    Verde Que Te Quiero Verde: Computación Sustentable

    Nuestro rancho Aquellos que siguen  mi blog en inglés saben que el número del Journal a aparecer hacia fin de año (es decir, no el siguiente Journal sino el que sigue a éste) estará abocado a explorar técnicas de computación eco-friendly. Esto es, que no dañen al medio ambiente (o que lo hagan, cuando sea inevitable, en la menor medida posible)

    Me está asesorando Lewis Curtis, arquitecto de infraestructura de Microsoft y una de las voces más activas en la búsqueda de iniciativas que permitan alinear más y más la tecnología a las necesidades de la sociedad -en todos sus estratos: social, empresarial, educativo, etc- con, al mismo tiempo, un mínimo impacto de daño en el ya desequilibrado equilibrio ecológico y que además, ya que estamos, permita reducir el consumo energético de todo el parque tecnológico, habida cuenta del encarecimiento en los costos que la generación de energía viene experimentando (que tarde o temprano se trasladan al consumo)

    De visita por mi oficina, Lewis me tiró unas ideas interesantes acerca de la correcta manera de entender y abordar la "Computación Verde" (Green Computing). Sintetizo su enfoque aquí

     

    6 aristas

    • Físico. En esta perspectiva se estudian alternativas para mitigar el calor liberado por el uso intensivo de las unidades centrales de procesamiento (CPUs). La concentración creciente de CPUs en espacios físicos de dimensiones reducidas torna los centros de datos (datacenters) en verdaderos infiernos. Literalmente hablando. Aquí no son solamente los fabricantes de CPU (Intel, AMD, etc) quienes están batallando para lograr una mejor ecuación performance-per-watt (rendimiento por electricidad consumida) sino que existen algunos estudios que detallan la ideal posición física de las CPUs para que estén lo suficientemente separadas como para que el incremento de temperatura no se potencie pero a la vez lo suficientemente cerca como para maximizar el aprovechamiento del espacio físico
    • Plataforma Operativa. Cuando se asignan procesos a servidores, se lo hace normalmente en función de la carga esperada de trabajo que estos procesos van a tener. El estudio de un consumo más eficiente de recursos dio lugar a dos tácticas: la optimización y la consolidación. La optimización del uso de la plataforma operativa se puede alcanzar de varias maneras, sea mediante la asignación correcta de recursos (CPUs, ancho de banda, etc) como por la detección de estado ocioso prolongado y consecuente hibernación, entre otras (esto, claro está, es también lograble desde el mismo hardware). La consolidación tiene que ver con la aglomeración de varios procesos en un mismo hardware, de modo de maximizar el uso de recursos
      Claro, acá puede impactar el hecho de que diferentes procesos pueden requerir una diferente plataforma operativa, lo que limita las chances de consolidación. Pero esto es mitigado gracias a los avances alcanzados en virtualización de plataformas, lo que ha permitido tirar viejo hardware, costoso de mantener, sin discontinuar las aplicaciones que en el mismo corrían -en muchos casos sistemas legados o legacy systems, los cuales hasta cierto punto pueden resultar tan caros de mantener como de migrar-
    • Regulaciones. A nivel gubernamental los países están avanzando (?) en metas de reducción de niveles de dióxido de carbono (CO2), el principal responsable del efecto invernadero (greenhouse effect). A la corta o a la larga eso se va a trasladar a un sistema de premios y castigos en la calidad y cantidad de energía que las compañías -y a renglón seguido los hogares- consuman. Probablemente esto vaya ligado a excensiones o gravámenes impositivos
    • La "Nube". Las aplicaciones hosteadas en la web misma, y con esto no me refiero a accesibles vía web ya que esto incluye a aplicaciones hosteables en un servidor hogareño, sino a aquellas aplicaciones cuyo "dueño" las recibe distribuidas como un servicio ("as a Service"), en lugar de hacerse responsable de su ubicación física y operación; decía que tales aplicaciones plantean desafíos tanto para el que las consume -quien no debe hacerse cargo del datacenter con lo cual acá tiene un significativo problema menos- como del que las provée, quien tiene ante sí la oportunidad de optimizar la granja de servidores, consolidando los clientes de tales aplicaciones SaaS (por Software as a Service o Software como Servicio). En la ecuación general, bajo este esquema de tiempo compartido (tiempo de ejecución, claro, o creíste que pusimos SaaS y nos rajamos todos de vacaciones... Zaas! smile_omg), el consumo de recursos y de energía es inferior al esperado por el esquema tradicional donde cada consumidor se hostea su aplicación en sus propios servidores (lo que se conoce como on premise delivery)
      Cuanto mayor sea la penetración del esquema "as a Service", mayor el ahorre global. Sin embargo, claro, pasar de la nada a este esquema no es fácil, sobre todo si se necesita que la parte hosteada en la nube interopere con lo que nos quede on premise. Qué de la atomicidad de las transacciones, qué del single sign-on (login único o SSO), qué de muchas otras tantas cosas como disponibilidad, tiempo de respuesta, etc
    • Inteligencia Sustentable. Imaginate un tablero de control donde podés monitorear la energía consumida por tu plataforma respecto de la actividad real que cada una está haciendo. Imaginate que podés establecer umbrales de consumo, disparar alarmas. Imaginate que podés tirar estadísticas históricas de ese consumo a fin de determinar tendencias y consiguientemente predecir la demanda futura esperable. No hace falta imaginarse demasiado porque existen esos monitores. Scry, Cognos (adquirido por IBM) por mencionar algunos de ellos
    • Código de Aplicación. Y llegamos al último, que a su vez engloba a todos los anteriores. En pocas palabras, no es cuestión de echarle la culpa de todo a la infraestructura, al soft de base e ilusionarse con la idea de que la solución pase nada más que por ahí. Por ejemplo, en nuestra apliación distribuida, dónde se conserva el estado de la sesión de cada usuario conectado? Es ese estado persistido al cabo de un tiempo en que el usuario no da señales de vida (y siempre antes de que expire su sesión), a fin de liberar la memoria para otras sesiones activas? Son los servicios state-less (una instancia única para todos) o stateful (una instancia individual por cada sesión que los consume)? Y qué hay para decir del ancho de banda? Se usa en forma eficiente? Qué significa "ancho de banda eficiente"? Enviar la menor cantidad posible de información en cada interacción o tratar de anticipar cierta información que el caso de uso pueda necesitar con una alta probabilidad? Y qué se puede decir del paralelismo en plataformas de más de un núcleo? Se saca tajada del procesamiento paralelo o el binario de la aplicación está pensado para el denominador común mono-núcleo? Podría seguirme extendiendo pero creo que con ésto queda demostrado que nosotros desarrolladores de soft no podemos hacernos los osos por muy ecológico que sea todo este tema

    Bueno, la consigna es enviar propuestas de artículos para computación verde que tengan un enfoque práctico (es decir, más allá del mero mensaje de que ahorremos gas, apaguemos luces y no imprimamos mails si los podemos leer de la pantalla). El plazo de envío se extiende hasta el 10 de Septiembre. Más detalles para hacernos llegar tu propuesta, acá

    August 02

    Mi Primer Journal Está en la Calle (#16, Identidades y Acceso)

    Portada y editorial del numero 16 de The Architecture Journal

     Dos años atrás,  cuando un artículo mío era publicado en una revista independiente de TI, un colega me dijo, "Vos deberías escribir para The Architecture Journal." No podía haber predicho que me iba a encontrar ahora escribiendo para esta revista en mi nuevo rol de editor. Le quiero agradecer a Simon Guest, por esta oportunidad y este enorme compromiso -durante su lapso, la cantidad de lectores se más que duplicó, pasando de 30 mil a más de 62 mil

    En este número, te invitamos a pensar en la Arquitectura de Identidades de tu organización. El manejo de identidades está evolucionando hoy del escenario simple, aislado, al escenario federado, en una forma que te puede sorprender

    Empezamos este decimosexto viaje con la introducción de Fernando Gebara Filho a los conceptos y estrategias en identidades, cómo han evolucionado y el camino por recorrer. Después, Jesús Rodríguez y Joe Klug examinan un surtido de estrategias para hacer de las identidades componentes de primera línea en el portfolio de aplicaciones federadas. Gerrit van der Geest y Carmen de Ruijter Korver consideran el desafío de establecer un entorno de confianza a nivel de aplicación ya que las identidades de usuario, en un mundo orientado a servicios, deben fluir desde el consumidor de un servicio hacia el prestador

    Para el perfil de arquitecto de este número, lo atajamos a Kim Cameron, autor de "Las Leyes de la Identidad", cuyas ideas en identidades federadas están dando forma a la siguiente generación de tecnologías de identidad de Microsoft. (Algo gracioso pasó el día que visité a Kim para esta entrevista: me olvidé mi tarjeta de acceso por lo que necesité que Kim "certifique" mi identidad en la entrada)

    Retomando nuestro paseo, Mario Szpuszta describe cómo el sistema de salud austríaco convirtió una crisis administrativa de provisioning en una clara oportunidad para crear una federación de identidades abierta. Luego Vittorio Bertocci explica cómo ciertos patrones de arquitectura nos ayudan a construir soluciones que consideran demandas (claims), de modo que cuando "la Nube" llegue a las compañías, el manejo de identidades no se va a ver necesariamente nublado

    Finalmente, Mike Morley y Barry Lawrence revelan cómo sincronizaron identidades en varios sistemas y aplicaciones legadas (legacy applications) desde una consola administrativa individual a través de un framework de consolidación

     

    Querido lector, quisiera ser el primero en darte la bienvenida a este número, y deseo que te sientas identificado con sus artículos. A disfrutarlo!

     

    Diego Dagum

    Editorial del numero 16 de The Architecture Journal

    July 11

    Call for Papers Para el Número 17 de The Architecture Journal

    Yo quiero escribir para el Journal El próximo número del Architecture Journal se va a enfocar en Computación Distribuida

    Nos estamos arrimando a un punto de inflexión con el hardware y las tecnologías de hoy donde lo que hace unos pocos años atrás era apenas una visión hoy se va haciendo realidad -desde distribuir aplicaciones a dispositivos microscópicos hasta datacenters del tamaño del estadio de Boca y aún más, que ofrecen correr aplicaciones en la nube

    No importa qué tan chico o grande, la distribución y la concurrencia de servicios múltiples puede introducir un número de desafíos

    El foco de esta edición es entender cuáles son esos desafíos y cómo superarlos

     

    Si esto logra inspirarte lo suficiente como para querer llevar tus opiniones a los más de 60000 lectores que el Journal tiene (solamente contando la edición en inglés, sin considerar las otras tres traducciones), por favor averiguá más datos en mi blog en la lengua de William (foto)

    June 01

    Recontruir Desde Adentro: Libro de Danija sobre Refactoring

    "La optimización temprana es la causante de todos los males"

    -Sir Charles Antony Richard Hoare, computador científico británico, después parafraseado por Donald Knuth en su libro El Arte de Programar Computadoras

     

     

    Días atrás, mirando un documental sobre la vida del director de cine sudamericano Fabián Bielinsky, me llamó la atención algo que dijo en una entrevista. Decía que, cuando se filman escenas, usualmente pasa que una toma determinada no sale como el director inicialmente asumió que iba a ser. A veces esa escena se hace de vuelta hasta que el director consiga lo que quería, en tanto que en otras ocasiones se deja no más como salió, en la medida en que así como está queda bastante mejor que la idea original. Bielinsky concluía que el verdadero arte de hacer cine es saber decidir cuándo intentarlo de nuevo y cuando dejar lo que salió de entrada

     

    Sorprendentemente, si así viene la mano con las películas, codificar componentes es muy parecido a filmar escenas. Siempre es posible encontrar una mejor solución a un algoritmo dado. Así que, con el sombrero de gerente en la cabeza, tenemos que decidir cuándo congelar una siempre posible mejora a efector del la carga GANTT, el presupuesto, las fechas de entrega y la satisfacción general del usuario, y cuándo ir por más

     

    Y es acá donde enfrentamos la necesidad de refactorización: una serie de técnicas y mecanismos para mejorar la calidad -comprensibilidad, mantenibilidad, modularidad, extensibilidad, etc- de segmentos de código mediante la reformulación de sus sentencias en una forma en que la conducta general no cambie. En otras palabras, el comportamiento de los componentes afectados no debería variar como una consecuencia del proceso pero su calidad, y ojalá su vida útil, debería ser incrementada

     

    La experiencia ha mostrado que algunas porciones de nuestro código van a ser, a la corta o a la larga, candidatas a refactorización, y las razones son varias:

     

    • Del lado del usuario, los usuarios no están completamente seguros de la aplicación que quieren hasta que ven instalado y corriendo lo que ellos pidieron originalmente. No es chiste! Al principio empiezan requiriendo algo que tienen en la cabeza pero vagamente (y eso es natural: de ninguna manera los estoy acusando). Olvidarse situaciones especiales cuando nos describen un caso de uso es como tener caries: no digo que sea bueno pero sí que es algo normal. Un efecto secundario indeseable de este tira y afloja es que nuestro código podría empezar a perder cierto grado de cohesión; sus diversos módulos pueden empezar a acoplarse arriba de los niveles aceptables como consecuencia de cambios de último minuto debidos a presiones del time to market
    • De nuestra perspectiva, la del desarrollo de software, nosotros no tenemos una idea cabal de a qué el código se va a parecer mientras estamos modelando. Al igual que los usuarios, nosotros también creémos que tenemos unas ideas impresionantes (o al menos buenas ideas al fin) hasta que tratemos de poner algunas de ellas en práctica. Equivocarse no es malo. Lo que es malo es obsecarse en cambiar de parecer sólo para evitar admitir que lo que habíamos considerado una gran idea no era, de hecho, tan fácil de implementar. Y acá de nuevo, cuando el tiempo agrega su presión, entregar un componente lo más rápido que podamos puede también dañar su calidad
    • Del lado de la tecnología, finalmente, hay una presión invisible aunque algo omnipresente a acompañar las tendencias de la industria. Ejemplos típicos son las APIs evolucionadas de .NET o Java (AJAX, servicios web, etc) que tornan obsoletas a las versiones previas, o estrategias generales como Arquitectura Orientada a Servicios (SOA), Modelo-Vista-Controlador (MVC), Mapeo entre Objetos y Relaciones (O/R-M), etc. Una vez más, en la medida en que reaccionamos a estas tendencias nuestro código es sometido a cierta manipulación que, a medida que el tiempo pasa, puede erosionar su calidad

     

    Mientras tanto, el mundo real nos muestra que esmerarnos en mejorar la calidad de nuestro código es algo que tendemos a hacer en forma innata. Las técnicas de refactorización no son sino el más alto grado de maduración de esos intentos espontáneos, reforzadas con algunas herramientas de soporte disponibles por ahí para garantizar el éxito del proceso

     

    La buena noticia es que podemos aplicar refactorización localmente, al nivel de un componente o método, allí donde estemos aplicando cualquier otra modificación; o globalmente, a nivel de módulo o aplicación, asignándole rango de proyecto. Decidir la dosis correcta de refactorización dependerá de la brecha de calidad a cerrar, el tiempo restante, el presupuesto disponible (siempre será más fácil justificar la refactorización donde ya teníamos algo más que hacer que donde ninguna actualización había sido pedida aún), entre otros factores

     

    A lo largo de este libro, el autor abordará tópicos de refactorización desde la visión de sus beneficios a las maneras actuales de ponerlo en práctica. Danijel Arsenovski ha estado involucrado en técnicas de refactorización, tanto en las plataformas .NET como Java, desde sus versiones más tempranas. Dio varias conferencias, charlas y talleres en esta materia, dirigiendo proyectos exitosos de refactorización en la industria bancaria

     

    Como uno de los líderes en herramientas de desarrollo, Microsoft ha estado comprometido a distribuir los mejores recursos para la gente que día a día lidia con actividades de codificación y proyectos de software en su totalidad. Mediante su indiscutidamente ganador entorno integrado Visual Studio, Microsoft hace de la refactorización una facilidad out-of-box apenas a un click de distancia de tu código. A lo largo de las páginas de este libro, Danijel te mostrará cómo la refactorización puede ser practicada en Visual Basic tan fácil como hacer copy / paste o cualquier otra actividad de edición!

     

    Me atrevo a decirte, estimado, que vas a encontrar en este libro una de las guías más probadas y fundamentales en estas técnicas. Que disfrutes este libro!

     

     

    Diego Dagum
    Evangelista Técnico, Microsoft Corp.
    Kingsgate, Invierno de 2007

     

    (Lo que acabás de leer es el prólogo que escribí para el libro de Danija "Professional Refactoring in Visual Basic" - Ediciones Wrox)

    May 11

    Crisis = Oportunidad. América Latina A No Dormirse


    La palabra Crisis, escrita en Chino, comparte un
    caracter con la palabra Oportunidad. No es así
    por casualidad

     No  es un secreto para nadie que el mundo se encamina a una recesión impulsada, esta vez, no por Brasil o Asia o Rusia sino por la primera economía mundial. Si se frena la locomotora (nos guste o no, es la primera unidad del convoy), los vagones que eran arrastrados inevitablemente van a perder impulso (nuevamente, nos guste o no)

    Curiosamente en medio de estas crisis es cuando, usando un poco de inteligencia, podemos ver el lado bueno en los cambios de contexto. Como la fábula del burro que iban a sacrificar y para eso habían hecho un foso, lo habían tirado al fondo y pensaban enterrarlo vivo: el burro logro salir del foso porque en la medida que la tierra que tiraban se iba asentando, hacía pie en ésta

    En el artículo que te linkeo acá, Gartner predice que en la medida que el parate económico de la primer superpotencia (la única hoy, bah) el outsourcing (tercerización) de servicios de software va a aumentar en forma considerable. El que la venía mirando con cariño, se va a decidir en la medida en que necesite mantener sus servicios de software (si es posible, incrementarlos para -en la crisis de demanda- mejorar la calidad de su oferta). El que ya estaba tercerizando y conoce las ventajas en lo que a reducción de costos se refiere, probablemente quiera cerrar un cachito más la brecha. Y finalmente, el que hasta ahora no pensaba en tercerizar, si empieza a estar con el agua al cuello quizás al menos comience a explorar esta alternativa (algo es algo)

    Gartner predice que India primero y China después van a ser los grandes polos de atracción de tercerizadores. Latinoamérica no sale mencionada, no en el informe de Gartner al que yo no tuve acceso, sino en la nota que lo destaca

    De todas maneras, si la montaña no viene a Mahoma, habrá que ir a la mountain no más... A preparar esas brochures en inglés. Primer mundo: allá vamoooooosssssssss!!!!!!! blacksheep

    May 08

    Arquitectos al Divan

    image

     Semanas  atrás liberamos la edición 15 del Architecture Journal (on line, revista en papel y reader). El tema de este trimestre es El Rol del Arquitecto, que es algo que siempre da que hablar. Más allá de cualquier tema que podamos cubrir de arquitectura de software (SOA, SaaS, O/R-M, etc) el éxito de un enfoque arquitectónico no lo va a dar por sí solo su diseño sino las habilidades del arquitecto en transmitir una idea en forma convincente, generar adhesión y lograr apoyos (tanto de arriba -léase guita- como de abajo -mano de obra leal que haga lo que los planos decían-)

    Al fin y al cabo, como decía el dicho, de carne somos y eso vale tanto para los arquitectos como para los que tienen que lidiar con ellos en el día a día (jefes de proyecto, gerentes de TI, desarrolladores, operadores, DBAs, jefes de seguridad informática, etc)

    Por esta razón hemos liberado un nuevo foro de discusión sobre el Rol del Arquitecto. La consigna del mismo no es debatir temas de arquitectura en general (onda "qué me conviene, ADO.NET o NHibernate?") -eso ya tiene su foro- sino lo que vendrían a ser nuestros soft skills como liderazgo, apertura intelectual, capacidad de aprendizaje y evolución, etc

    Te recomiendo que afiles tus conocimientos de inglés y te pegues una vuelta. Se han armado unos debates bastante interesantes ("debe un arquitecto programar? cuánto?", "cómo lidiar con el jefe cuando nos fuerza a hacer la arquitectura contemplando cosas que nunca hubieramos elegido?", "por qué no se puede ser arquitecto apenas se sale de la facu?")

    Y muchas otras

     

    Oíme, haceme caso. No gastés guita en psicólogo y vení a discutir de estos temas al foro. Como es de esperar, minitas no va a haber pero en eso al menos no estabas mejor en el psicólogo

    May 04

    Consultorio Dr. Diegumoff. Hoy: Responsabilidades del Arquitecto

    Hospitales_OK_1 
    Parálisis de Diseño? Implementación Precoz? Consulte al Dr. Diegumoff

     

     Recibí  una consulta interesante de Jorge, un lector del blog, docente de la carrera de computación científica en la Universidad de Ciencias Informáticas (Cuba). Preferí -previa autorización de él- llevar el caso en forma abierta, de modo que todos puedan dar su visión al respecto

     

    From: Jorge
    Sent:
    Friday, April 18, 2008 7:59 PM
    To: Diegum

     

    (...)

    Leí tu blog “Rol del arquitecto: Reglas del Juego” y coincido contigo en lo que comentas sobre los roles en la teoría y la asignación de los mismos en la práctica, lo cual lleva a que muchas veces no se defina bien dentro de un proyecto hasta donde llegan las responsabilidades del arquitecto y a veces algunas se queden sin cubrir. Pero me pregunto si entre las responsabilidades del arquitecto también caen la definición de los siguientes elementos:

    · Plataforma de desarrollo.

    · Sistemas Operativos.

    · IDE a usar.

    · Lenguaje de programación.

    · Herramienta de modelado.

    · Herramientas de control de versiones.

    · Herramienta de gestión del proyecto.

    · Estándares de información.

    · Estilos y patrones arquitectónicos.

    Esta pregunta se debe a que un alto cargo de la universidad esbozó esto como tareas del arquitecto y la verdad que no coincido con él en este sentido, incluso busqué en algunas metodologías de desarrollo y por ejemplo en RUP estas determinaciones forman parte del flujo de trabajo de Ambiente, y no le corresponden al arquitecto, menos la de estilo y patrones arquitectónicos.

    Saludos, y gracias de nuevo por permitirme contar contigo.

    Jorge.

     

    Estimado Jorge, el caso que se te planteó es de esas típicas discusiones donde todas las partes involucradas parecen tener algo de razón, lo que vuelve muy complicado de determinar quién está en errado y quién no smile_wink

    Es muy probable que si afirmamos que sólo al arquitecto le cabe definir la plataforma de desarrollo, los sistemas operativos sobre los que la solución va a correr, elegir el IDE, etc, estemos equivocados. No obstante, sería falso también decir que al arquitecto no le cabe ningún rol en las decisiones a tomar en esos primeros puntos de la lista

    La mano es así: arquitectos los hay con distinto nivel jerárquico, esto basado en su background, antigüedad en la empresa donde trabajan, antigüedad en la industria del software, etc. Asimismo, tenemos arquitectos de soluciones (que son los que vienen de haber programado durante varios largos años) y arquitectos de infraestructura (aquellos a los que les tocó instalar y mantener servidores, redes, puestos clientes y periféricos durante un lapso no menor)

    Es muy raro -aunque no imposible- que te topes con alguien que la tenga clara en desarrollo y a la vez la tenga clara en infraestructura. Cuando te digo "tenerla clara en ambas cosas" no me refiero a saber Java y ser capaz de instalar Linux, sino a ser capaz de diseñar soluciones que corran en una plataforma definida por ellos y que la cosa escale así de repente todos los usuarios se decidieron a dar enter al mismo tiempo smile_wink

    Seguramente que lo que dijo el profe pueda parecer exagerado si se lo vamos a asignar, dado un proyecto x de misión crítica, a una sola persona aunque lo probable es que sean definiciones a resolver entre dos o quizás más. Lo que sí me atrevo a asegurar es que varias de estas personas van a ostentar el rol de arquitecto (o arquitecto jefe, que es más bien un arquitecto que no participa en un proyecto dado sino que toma decisiones que afectan a todos los proyectos de la organización). Lo más probable es que estos arquitectos sean, algunos "de soluciones" (desarrollo) y otros "de infraestructura"

    Si tengo que contar por mi caso personal (yo soy arquitecto de soluciones), hubo proyectos a los que me sumé y ciertas decisiones ya habían sido tomadas (S.O., Lenguaje de Programación, etc) y otras que aún quedaban "por tomar". Para aquellas que aún estaban pendientes, como te contaba, no es que me tiraban toda la responsabilidad de la decisión a mí solo, sino que yo integraba un comité junto con otras personas

    La mayoría de las veces, tal como tú lo sugieres, tuve voz pero no voto. Es decir, podía dar mi opinión pero la decisión quedaba en manos de alguien con "poder de compra", sobre todo en aquellos casos en que la decisión implicase adoptar un producto con un modelo de licenciamiento lucrativo (que haya que pagar para poder usarlo, bah). Debo confesar acá que me frustraba que a veces mi opinión fuese ignorada (me carcomía la duda de para qué me convocaban a esos comités si luego iban a hacer lo que les pareciera. Pero, en fin, volviendo al punto y como cierre, no es que me tocara toda la responsabilidad a mí pero sí al menos una participación en la maduración de las ideas y los rumbos a tomar

    Sin duda alguna que, no obstante, el grueso del proyecto lo iba a dedicar a "Estilos y Patrones Arquitectónicos", el último punto que mencionó el profe y con el que sí estuviste de acuerdo

    Saludos por la tierra del Ron

    April 20

    Middle-Out: Un Gol de Media Cancha

     Los  manuales suelen hablar de dos enfoques para abordar diseño de aplicaciones: el top-down (o "desde la cima hacia abajo") y el bottom-up (o "desde el fondo hacia arriba"). Ambos enfoques son complementarios, no alternativos. Es decir, están pensados para ser ambos aplicados en un proyecto, no son dos tendencias antagónicas como ocasionalmente pueda verselo presentado. Veamoslo más en detalle

    • Top-down es el enfoque "políticamente correcto" en el sentido que parte de premisas puramente organizacionales (o para no hacerme tanto el delicado, "necesidades de negocio", bah; quise probar otra cosa porque siempre digo "business needs" y ya suena un poco cacofónico pero al fin y al cabo, es eso). Se basa en un principio caro a las ciencias de la computación que es el de "divide y reinarás" ("divide and conquer" en la bibliografía en inglés), donde se parte de un contexto macro que ciclicamente será descompuesto en sus partes constituyentes, éstas últimas en sus propias partes constituyentes y así sucesivamente hasta llegar a ciertos límites donde el proceso de introspección se detiene porque se ha logrado un modelo con cierto nivel de atomicidad tal que se pretende satisfacer con componentes ya disponibles (sean propios o de terceros, ya no es necesario "reinventing the wheel" o reinventar la rueda. Es justamente llegados a este borde que el siguiente enfoque entra en juego
    • Bottom-up gana presencia una vez que los átomos consituyentes de las diversas capas de componentes han sido determinados. Entonces se sigue por asignar tecnologías (componentes, plataformas) como una forma de comenzar a desenmarañar la espiral de componentes en que el modelo ha derivado. Y digo "comenzar" a resolver debido al readiness de los componentes atómicos (qué tan listos para usar vienen). Normalmente va a ser aún menester el cumplimiento de tres etapas con los mismos:
      • Construcción (building), para aquellos componentes planeados durante el top-down pero aún no disponibles
      • Configuración (customization), de los grados de libertad que el componente habilita para permitir adaptarse a un grado amplio de necesidades de modo de pelear hasta donde se pueda la batalla por la reusabilidad. Esta etapa transcurre especialmente durante el periodo de desarrollo en el ciclo de vida (software development life cycle o SDLC)
      • Afinamiento (tuning), especialmente durante el período de implementación -aunque empieza tímidamente al principio, desde la planificación de capacidad (o capacity planning) cuando se presupuesta la carga que la solución pueda llegar a alcanzar. Desde luego que ninguna de estas dos etapa se enmarca estrictamente en una fase del ciclo de vida sino que tienen fases donde logran más protagonismo. Podría darse, como una consecuencia del tuning, que se termine revisando la customización o la misma construcción de los componentes

    Para los puristas metodológicos, esa secuencia de enfoques (top-down y bottom-up) era condición necesaria y suficiente para decir alea jacta est (o la suerte está echada, como cuando Julio César desafió la autoridad del senado romano cruzando el río Rubicón pese a las advertencias de que no siga avanzando, aunque algunos historiadores dicen que pronunció alea jacta est queriendo significar la jalea está hecha -al parecer a este Julio le tiraban los dulces-). Estaba contando que para algunas personas, esta forma de trabajo garantiza el éxito. Pero en la última década se comenzó a sospechar de que ya no. O, al menos, no necesariamente. A continuación voy a tratar de explicar cuáles son los vicios derivados, y a mostrar y explicar cuál es la alternativa que ha venido emergiendo victoriosa

     

    En principio el esquema planteado por estos dos enfoques ha venido asociado durante décadas a ciclos de vida en cascada (waterfall). Esto es, una vez finalizada una etapa del ciclo de vida, ya no se volvería a ella hasta el final del proyecto (inflexibilidad de por sí arriesgadísima, como desde luego la experiencia se encargó de mostrar). Permiso aquí: no es que los promotores de top-down/bottom-up impusieran waterfall sino que el timeframe en que top-down y bottom-up fueron moneda corriente coincidió con la edad de oro del waterfall. Y es que si bien estos dos enfoques se pueden aplicar a un proceso ágil, la dinámica geeky impartida por este último (un diseño medio a mano alzada y a programar de una smile_teeth) tornaría las sucesiones top-down/bottom-up algo toscas
    Como fuera, la reputación de los procesos en cascada hoy viene (de la boca para afuera) de capa caída. En la práctica, luego de décadas de cascadas, torrentes y cataratas, la corriente del waterfall todavía sigue tirando (es muy dificil romper esa cultura, sobre todo en las áreas gerenciales en que quieren ver una carta GANTT previsible -que a su vez deben presentar al directorio, si es por ellos, con que funque da lo mismo-)

    El esquema dual top-down/bottom-up también tuvo y tiene dificultades en hacer congeniar dos mundos: el de los líderes de TI y sus reportes. Generalmente son los líderes de TI o los líderes de los proyectos los que se encargan de la etapa top-down, en tanto que los developers y operadores (a veces conocidos como profesionales de TI o IT Pros) suelen llevar a cabo el bottom-up

     

    Se suele dar algo curioso con los arquitectos, que ya venía contando el mes pasado en mi post "Reglas del Juego". Dependiendo de la vereda en la que estén parados (si la del negocio mirando a la tecnología o si viceversa), tendrán una tendencia a participar en la etapa top-down o en la bottom-up respectivamente
    Yo puedo decir que hoy estoy marcadamente tirado más al momentum del top-down (o, dicho en otras palabras, cuando llega el momento de programar me borro smile_tongue). En cambio, en mis tiempos como arquitecto Java EE -por aquellos días J2EE- me acuerdo que aunque creyera ser business-oriented, era eminentemente bottom-up: no podía dejar de ver los sistemas en términos de APIs (APIs a las que dedicaba días y noches enteras en entender hasta el más mínimo detalle de sus capacidades smile_nerd). Esto obviamente me desenfocaba a menudo la lente con la que debía mirar (y entender) el espacio del problema
    Con todo, y a modo de conclusión, debo decir que un arquitecto debe participar tanto en la descomposición top-down como en las decisiones a tomar durante la fase bottom-up. Más allá de cuáles sean sus fuertes o qué le tire más, debe hacer el esfuerzo por desarrollar el otro hemisferio

     

    Esto que me pasó y me sigue pasando, suele pasar en general y si le tengo que asignar un nombre, debería éste ser "la brecha entre top-down y bottom-up" ("top-down/bottom-up gap", suena lindo, no? smile_shades)

     

    Figurativamente hablando, es como si ambos enfoques fuesen las dos secciones de un puente levadizo. No hace falta convencer a nadie de que sin una de esas secciones no habrá forma de cruzar el puente que lleve desde el espacio del problema hacia el de la solución. Pero aún estándo presentes, puede darse el caso de que las secciones no logran unirse. He aquí el famoso gap o brecha entre los dos enfoques
    Algunas vez Jotapé se refirió a esto en un post recomendable. Él aborda el caso en que top-down no baja lo suficiente pero no es ciencia oculta imaginarse la otra cara del problema: un bottom-up demasiado centrado en sí mismo que no honra las necesidades por las cuales tuvo su raison d'être (merde! smile_omg)

     

    Como consecuencia de estos malestares, y quizás acompañando la caída en cáscada de los ciclos de vida waterfall, un nuevo enfoque unificado ha emergido: Middle-Out ("del centro hacia afuera"). Middle-Out implica dar lugar a la experiencia que nos supimos ganar en tantos años de industria (por ende, si sos un recién llegado, no digo que no debas aplicar este enfoque pero quizás no vas a tener el suficiente marco de referencia), de manera tal que no vamos a partir desde el confín más sui generis del espacio del problema sino que vamos a mezclar un cachito de lo que conocemos del problema con lo que la tecnología ya avisora como solución (patrones de arquitectura, de diseño, productos de mercado -sobre todo los que la organización ya adquirió y por ende ahora hay que amortizar si no queremos aparecer una mañana leyendo los clasificados de demanda de laburo smile_tongue)

    Middle-Out se para justo en esa mitad donde las dos secciones del puente se juntan, y avanza hacia sus extremos opuestos. Por eso mismo es fundamental lo que te decía de "la cancha" que es necesario tener para aplicar este enfoque: dónde está exactamente ese punto de unión? Sólo los que ya cruzaron varias veces estos puentes pueden saberlo con precisión

    Se descrée que haya sido Middle-Out el que provocó, como consecuencia, procesos de desarrollos ágiles. Más bien se considera que el enfoque Middle-Out es una consecuencia de estos. Lo cierto es que caminan muy de la mano. El esquema iterativo e incremental de los procesos ágiles es el que permite, sea cual fuere el punto intermedio de partida, converger hacia las salidas (un EXIT total smile_shades)

    Lo que le da a Middle-Out fortaleza para ganar adhesión en los estratos más altos de la gerencia es, a esta altura del partido, la percepción de que el espacio del problema no sólo no es -como regla general- del todo conocido por quienes definen la necesidad (las gerencias operativas y administrativas de la organización) sino que incluso aquello que si conocen puede cambiar de acuerdo a los vaivenes empresariales (impuestos reactivamente ante movidas de la competencia o proactivamente hacia nuevas oportunidades a encarar)

    Middle-Out es, en realidad, algo que innatamente hacemos en las restantes cosas de la vida. Cuando tus amigos te proponen hacer un asado el finde les preguntás "quién lleva el vino?" siendo que no hubo un análisis desde el principio respecto de si los comensales toman alcohol, qué hacer en caso de que llueva, etc) y no hay nadie que esté, desde lo más abstracto, pensando en costo/beneficio de organizar un asado, etc

    De todas maneras, no tengas dudas de eso, no es que Middle-Out debe a partir de ahora ser el enfoque único y que la dupla top-down/bottom-up pasan a mejor vida. Todavía existen escenarios donde estos enfoques van a prevalecer y en cambio Middle-Out va a quedar descolocado. Te menciono algunos, a modo de cierre del post

    • El proyecto tecnológico comienza desde un análisis ya realizado en forma completa o casi completa por consultores. El qué de la solución (o el espacio del problema, si se quiere) ya se tiene claro y es posible que no cambie demasiado. Sólo resta completar con el bottom-up si bien es cierto que, en lo que respecta a nosotros, estamos empezando por el medio (pero no vamos a avanzar hacia arriba smile_wink)
    • Imaginate ahora un escenario similar al anterior pero donde además, antes de irse, los consultores esbozaron como parte de sus conclusiones una propuesta de implementación (tipo "orquestación Biztalk disparando contra el Oracle en un CICS, además de la base SQL local") que fue aprobada por el comité ejecutivo del proyecto. Entonces te dan ahora la batuta a vos como arquitecto y... al menos la infraestructura ya no la vas a tener que definir porque alguien se encargó de pensar (no importa si bien o mal, la cosa es que ya lo hizo y le creyeron!! smile_tongue). Te restará entonces definir la solución a montar en dicha infraestructura. Es por un lado limitado pero por el otro desestresante el no tener que decidir sobre absolutamente todo, creéme
    • Otro caso más que no sería Middle-Out puro (aunque se le asemeja bastante) es el caso en que no hay aún una etapa top-down concretada... pero sí gran parte de la bottom-up!! Que cómo es eso me preguntás? La organización, luego de un excelente desempeño de labia de vendedores o consultores de una empresa externa, adquieren determinada infraestructura y definen que todo nuevo proyecto la va a usar (por los beneficios que dicho producto aporta), en tanto que viejos proyectos legados se irán migrando conforme se pueda a dicha plataforma. Como te contaba, no llega a ser un Middle-Out 100% aunque podríamos decir que en tanto que no toda la infraestructura esté definida, empieza a tomar forma de
      • Esto en verdad va a depender porque todavía la gerencia te podría indicar que, más allá de que parte del bottom-up ya esté prefijado, a vos te toca partir desde el top-down y no desde el medio. Si ése es el caso, no sería Middle-Out ni puro ni impuro: es top-down/bottom-up a la vieja usanza

     

    Estimados, ha sido un placer y me despido hasta la próxima

    April 08

    Identity Architectures (Arquitecturas de Identidad) - Call for Papers

     Hay  un nuevo llamado para propuestas para el Journal de Arquitectura (#16). Como esa publicación es en idioma inglés, prefiero directamente referenciar al aviso en la lengua de Shakespeare

     

    http://blogs.msdn.com/diegumzone/archive/2008/04/05/microsoft-architecture-journal-issue-16-call-for-papers.aspx

     

    Anyway, si te querés enterar antes que nadie de los futuros llamados, suscribite a este feed: http://www.microsoft.com/feeds/msdn/en-us/arcjournal/rss/rssCallForPapers.xml

    April 07

    Sistemas de Alto Rendimiento: la Carrera por la Computación Paralela

     Es  un hecho que hoy en día los equipos con dos procesadores son un estándar, y opcionalmente los hay de cuatro o más CPUs. Normalmente dos procesadores es la norma hoy en equipos cliente o "de escritorio" en tanto que más es norma para equipos servidores

    En estos casos se suele dar que las primeras aplicaciones que sacan provecho de estos avances son las de nivel más bajo como el sistema operativo o procesos servidores como el RDBMS (la base de datos, bah), etc

    En una segunda oleada estos beneficios pasan a ser dejados a disposición del público masivo, como ya pasara con los procesadores gráficos que al principio quedaban accesibles sólo a través de APIs especiales como DirectX y hoy cualquier mamerto con Windows Presentation Foundation pueden hacer aplicaciones que la gente diga "wow!" (lo de "cualquier mamerto" va por mí: el Architecture Journal Reader, canejo smile_shades jah!)

    Que al comienzo las APIs sean realmente complejas obedece a dos razones:

    • No están sus creadores lo suficientemente maduros en su entendimiento de las mismas como para poder ponerlo en términos más simples (para ello en realidad deben usarlas intensivamente de modo de extraer de esa experiencia las mejores prácticas), y
    • Como corolario de lo anterior, en cierto modo la idea es privar al público masivo de un acceso irrestricto hasta tanto no se vean formas de encapsular esos mejores usos en APIs que eviten provocar un malestar generalizado con estos avances

    Pero lógicamente, ya va llegando el momento y por ende la idea es poder brindar a las plataformas de desarrollo actuales de estas herramientas que allanen la curva de aprendizaje

    Asistimos en estos días a una carrera en el segmento de las plataformas administradas (tanto Java como .NET) para cumplimentar este objetivo. Para hacer honor al tema del post, Paralelismo y Concurrencia, voy a enlistar lo que .NET y Java están armando al respecto en forma paralela y concurrente (jeh, soy un piola yo... smile_tongue)

     

    .NET Framework

    Java Standard Edition

    • Se lanzó un portal MSDN para desarrolladores en Computación Paralela
    • El mismo tiene desde artículos introductorios, a contenido más específico al respecto (con ejemplos de código de lo que sería la futura API)
    • Esto va coronado con, para aquellos que quieran hacer pruebas de concepto (proofs of concept o PoCs) con un preview de PFX (o Parallel Extensions for the .NET framework) para extender sobre .NET 3.5 (lo que da a entender que esta facilidad, de liberarse, será para una versión seguramente posterior)
    • También hay videos, donde no puedo dejar de recomendar el realizado por Anders Hejlsberg, gurú de los lenguajes de programación y padre de Delphi y C#
    • Entre otras cosas, también se puede ver cómo PFX va a impactar en otras APIs existentes como LINQ (una API que facilita las consultas sobre colecciones de datos, sea que estos estén en memoria, en una tabla relacional, en un archivo XML o donde fuere). A esta unión lo he visto descripta como PLINQ (o Parallel LINQ, a mal entendedor muchas palabras smile_regular)
    • Para cuando la versión 5 de Java Standard Edition fue liberada (segunda mitad del 2004), una biblioteca (o paquete, y que me perdonen en Chile smile_embaressed) llamada java.util.concurrent permitía sacar provecho de equipos multiprocesador aunque en forma indirecta: esta biblioteca contenía componentes que hacían uso de esa característica para que los programadores consuman dichos componentes (no para que créen los propios)
    • El Requerimiento de Especificación en que el comité que evoluciona la plataforma trabajó fue el JSR-166, Utilidades de Concurrencia
    • Ese mismo JSR está ahora siendo revisado para incluir facilidades que permitan programación concurrente en Java 7 (estimado para principios del 2009)
    • La estrategia se basa en dotar a Java de técnicas Fork/Join con la filosofía de descomponer un algoritmo complejo en partes secuenciales más simples, y analizar de éstas cuales en verdad no dependen mutuamente sino de otras partes en común (pero no entre sí) de modo que puedan paralelizarse
    • A quien se lo ve muy activamente trabajando en esto es a IBM, quien a través de su portal DeveloperWorks ha publicado dos artículos al respecto

     

    Será hasta la próxima

    March 31

    Rol del Arquitecto: Reglas del Juego

     Una  de las principales razones por las que ha venido siendo tan dificil definir qué es un arquitecto es por la falta de acuerdo en cuanto a lo que un arquitecto debe hacer. Cómo distintas perspectivas le asignan a dicho rol distintas responsabilidades, por consiguiente el rol en sí mismo pasa a ser diferente según la perspectiva de donde se lo evalúe

    Esto me empezó a dar vueltas en la cabeza estos últimos meses, ya que con Simon estuvimos trabajando fuerte en el número 15 del Journal de Arquitectura, próximo a aparecer (*). El tema de este decimoquinto número es, justamente, el Rol del Arquitecto

    Como siempre hubo un call for papers (que tuvo lugar durante el pasado mes de Enero), y varias propuestas fueron recibidas, de las que escogimos unas siete u ocho. De estas seleccionadas fueron luego llegando los primeros borradores, por lo que puedo decir que me he pasado el trimestre que va terminando dando vueltas cuan pollo al spiedo alrededor del bendito rol que nos toca jugar

    Y lo que puedo anticipar de la edición que estás por recibir es que, como era de esperar, varios artículos se parecen entre sí en el sentido que hablan de un personaje con el que nos identificamos; pero al mismo tiempo discrepan entre sí, porque le atribuyen responsabilidades o conductas que nos puedan sonar cuestionables

    Entonces pensé que, como siempre, el origen de las divergencias se remonta a la clásica subdivisión del perfil de arquitecto en

    • Arquitecto Empresarial (o Estratégico)
    • Arquitecto de Desarrollo (o Soluciones)
    • Arquitecto de Infraestructura

    Yo asumo que esta subdivisión ya la manejás de taquito, pero si ése no es el caso, leéte este artículo de Simon que lo cuenta bastante claro

    La clasificación no está mala y, sobretodo, no es algo que un solo vendor impuso sino que hay no sólo un consenso en la industria: el framework de arquitectura conocido como TOGAF (The Open Group Architecture Framework) considera cuatro Dominios de Arquitectura (Architecture Domains). Estos son, a saber:

    Pero no termina acá, también la IEEE a finales de los '90 dio forma a su especificación IEEE 1471 (forma corta de referirse a Práctica Recomendada para la Descripción Arquitectónica de Sistemas de Software Intensivo), un estándar tanto ANSI como ISO. Esta especificación define Puntos de Vista (Viewpoints) nuevamente asignables a los roles antes descriptos

     

    Y sin embargo...

     

    Esta taxonomía está bien para organizar información relacionada con estos -tomando prestado de TOGAF- dominios de arquitectura antes descriptos. Pero no tengo claro que en la práctica necesariamente se dé que haya, en una misma organización, arquitectos cubriendo estos roles. No estoy diciendo que esté bien que sea así o que esté mal, sino que en la medida en que estos roles van madurando, las organizaciones ya venían lidiando a su modo con las necesidades a cubrir. Como resultado, tenemos que

    • Una misma persona cubre algunas actividades de uno o más roles, pero no todas las actividades que a ese rol le suelen asignar hoy los estándares
    • Un dado proyecto en una determinada organización puede requerir cierto nivel de cumplimiento con la definición de una arquitectura, pero a un nivel de detalle que puede resultar escaso según las normas de otra organización
    • Distintas organizaciones, partiendo de la base de que tienen distinto tamaño y diferente presupuesto de TI, lidian con distinto headcount (cargos a cubrir disponibles). Como resultado, las tareas de arquitectura a realizar se van a asignar al personal disponible (nuevamente conduciendo a que la relación entre roles y personas termine siendo cualquiera a cualquiera en lugar de 1:1, 1:n, m:n, etc

     

    Me siento lejos de la postura de decir que si en la práctica las cosas se dan así, es porque algo esté saliendo mal. Me ha tocado trabajar en proyectos donde ciertas decisiones que afectan a la arquitectura estaban ya tomadas (por ejemplo, plataforma J2EE contra base de datos Oracle sobre ambiente Linux, etc). Siendo esas las circunstancias, un arquitecto de infraestructura tenía poco margen de acción en cuanto a tomar decisiones de plataforma se tratase. Sin embargo, aún le cabía un rol preponderante en el despliegue de la solución (y la asignación de procesos a servidores, etc). No obstante, en los hechos, esta actividad de infraestructura terminó en más de un caso siendo cubierta por el "arquitecto" (así, en genérico) que era también el que diseñaba la solución a desarrollar. Obviamente que no cualquier arquitecto de soluciones podía estar ducho en la infraestructura elegida de antemano, como para definir la mejor manera de montar la solución, pero justamente eso era lo que hacía que ciertos proyectos atraigan a cierta gente que habría quedado al margen en otros proyectos que compartieran ciertas similitudes y ciertas diferencias (por ejemplo, plataforma .NET disparando transacciones vía Host Integration Server contra un CICS el que, a su vez, accede a una base de datos DB/2)

     

    Podríamos concluir que los roles oficiales tienen aparejados una serie de actividades, pero que en la práctica de ese menú total de actividades habrá algunas que van a ser cubiertas en forma total, otras parcialmente y aún otras ignoradas

    Estas actividades van a ser asignadas a diferentes arquitectos (en genérico) pero no necesariamente según rol sino considerando, en cada caso, el conocimiento que tengan del negocio y la cultura de la compañía, de la plataforma de desarrollo y de los ambientes de ejecución. En ese contexto, no va a ser descabellado aprovechar el expertise de un miembro del proyecto en -digamos- aplicar sintonía fina (fine tuning) a un esquema en Sybase, si bien su actividad principal sea la de definir y liderar el desarrollo de un framework de acceso a datos que encapsule la complejidad de APIs como JDBC o ADO.NET

    Será tarea del líder de proyecto, en base a las circunstancias actuales del mismo, definir qué actividades de arquitectura estarán presentes y en qué grado, y a quién/es serán las mismas asignadas

    ____________________________________
    (*) A propósito, desde el número 3 hasta el 14 (el actual) están disponibles en español

    February 24

    Qué Debemos Recordar Sobre la Pérdida de Memoria (Memory Leaks)

    Introducción: Pérdidas de Memoria en Java y .NET? Y el Garbage Collector? Funca mal? 

    Memory Leak Se  suponía que esta generación de lenguajes dentro del rango conocido como código administrado (managed code) iba a terminar con el dolor de cabeza que habíamos padecido los que -sea en Pascal como en C o C++ o cualquier otro lenguaje que permitía referenciar memoria a través de punteros (pointers)- tuvimos alguna vez que lidiar con manejo dinámico de memoria (esto es, pedirle memoria al sistema operativo y devolvérsela luego)

    Sin embargo me decido a escribir este post como respuesta a varias preguntas que he venido recibiendo de amigos que trabajan, sea con Java o con .NET, y que están padeciendo un problema que ellos pensaban que desde el vamos iba a estar superado

    Partamos por la definición: una pérdida de memoria (en inglés aparece como memory leak o fuga de memoria) es una situación que se produce cuando la aplicación no devuelve al sistema operativo franjas de memoria que ya tampoco va a usar. Generalmente con el agravante de que siendo que los datos en esa memoria son ya residuales, de necesitar espacio para nuevos datos, la aplicación va a pedir más memoria al sistema operativo al no considerar que tiene total o parcialmente espacio para alojar esta información

    Las pérdidas de memoria normalmente son procedurales. Es decir, la aplicación en la forma en que está programada, pierde memoria en forma sistemática de manera tal que nueva memoria solicitada al sistema operativo es también pasible de ser total o parcialmente perdida. De esta manera, dependiendo de la memoria original disponible, de la ocupada por procesos concurrentes, etc, siempre me alucino con la idea de que en algún momento el sistema operativo me saque una caja de diálogo como la siguiente

    Sin memoria

    La caja de diálogo de recién es una broma, claro. En cambio, lo que sí los sistemas operativos suelen hacer es asignar quantums de memoria a las diferentes aplicaciones, y aquellas que pasan cierto umbral de memoria requerida en un cierto tiempo son pasibles de ser penalizados por el sistema operativo, que puede comenzar por relegarlos a swappear ("intercambiar", del inglés swapping) su memoria entre almacenamientos primario y secundario, siguiendo por bajarles la prioridad de ejecución -para no pagar el mismo sistema operativo la penalización por swapping, ya que ese tiempo de intercambio se considera tiempo de ejecución del sistema operativo, no de la aplicación- hasta finalmente decirle a la aplicación su merecido "no va másssssss" como en la ruleta

    Esto último, los que programaron en Java lo recibieron en la forma de un java.lang.OutOfMemoryError, parecido al System.OutOfMemoryException de .NET -quiero destacar la riqueza expresiva de Java, que reconoce a los errores (java.lang.Error) como una categoría separada de las excepciones (java.lang.Exception); una excepción es eventualmente atajable (catch) en cambio un error implica un fallo fatal y la ejecución finaliza allí. Tal distinción no tiene paralelo en .NET-

    Ahora bien, las plataformas Java y .NET son entornos de ejecución administrados que cuentan con un recolector de basura (garbage collector). La idea del mismo -las implementaciones difieren algo- es detectar direcciones de memoria inalcanzables (por ejemplo, una variable local que se creo dentro de un bucle cuya ejecución ya quedó atrás; la variable es local al bucle y por consiguiente ya no hay forma de alcanzarla, ni siquiera definiendo otra variable con el mismo nombre o, si acaso, volviendo a ejecutar el bucle). A grosso modo, el recolector devolvería al sistema operativo esa memoria que venía siendo referenciada por variables que se quedaron fuera de scope aunque, en la práctica, a quien se la devuelve es a su propio montículo (heap) de memoria por si más adelante la fuera a necesitar. A su vez, sí, el montículo de la aplicación puede crecer o decrecer (pidiendo y liberando memoria al sistema operativo) pero en otros intervalos que los de la frecuencia del recolector

    Con esto dicho, el programador entonces no se entera de cómo la memoria es adquirida o devuelta por lo que si la aplicación toma ese recurso y luego no lo devuelve, todas las miradas se dirigen al entorno administrado (Java VIrtual Machine o JVM en la plataforma Java, Common Language Runtime o CLR en el caso de .NET). Y sin embargo, no: rebobinemos un poco la cinta hacia el párrafo anterior. Allí decía "la idea del recolector de basura es detectar direcciones de memoria inalcanzables"

    Ahí está el quid de la cuestión. En la medida en que instancias de objetos creadas sean alcanzables. Si los métodos que crearon estas instancias han devuelto referencias a las mismas, y a su vez dichas referencias fueron almacenadas como propiedades de otros objetos que son alcanzables, por transitividad las instancias creadas son también alcanzables. Ergo, si nuestras aplicaciones empiezan a dragar memoria en forma descontrolada, debo ser el portavoz de la mala noticia de que no vamos a poder irnos silbando bajito tan fácil Acá debo defender al gremio de los grandes distribuidores de plataforma: no es una falencia de la JVM o del CLR el no detectar que esta memoria de la que hablamos se debía haber liberado. Estos entornos de ejecución operan en una forma deterministica: es alcanzable, no se libera; no es alcanzable, se libera. Sin vueltas. El resto depende de nos, desarrolladores de software

    Escribo esto y me viene a la memoria la típica reacción que he visto en desarrolladores cuando sienten que la aplicación no libera memoria en la proporción que esperarían: forzar la llamada al recolector de basura. Esto al menos en la plataforma .NET no va a sino empeorar las cosas, como voy a mostrar a continuación

     

    Cómo Trabaja el Recolector de Basura

    La memoria de una aplicación .NET está organizada en varios segmentos. Uno de ellos, particularmente, es el llamado "segmento de memoria administrada" que es aquella que es reservada y liberada directamente por el CLR (en contraposición a otros segmentos, como el de "memoria primitiva" o "no administrada" que es el segmento de la memoria que el mismo CLR reserva para sí -la que él necesita para ejecutar nuestra y otras aplicaciones- y también aquella memoria que nuestra aplicación reserva en forma directa, por ejemplo en C++ o C#, mediante llamadas explícitas al sistema operativo). Pero volvamos al que nos interesa, el segmento de memoria administrada:

    En el mismo, a su vez, el montículo se organiza en generaciones. Esto es, por diseño, el CLR asume que si un objeto sobrevivió un determinado período de tiempo, entonces es probable que sobreviva por algún tiempo más. De esta manera, cualquier nuevo objeto que es creado se dice que pertenece a la generación 0, cuyo tiempo de vida se presume limitado. Entonces en un dado momento el CLR se va a encontrar con que el montículo no tiene memoria suficiente contigua para el siguiente comando new. Como consecuencia el hilo del recolector de basura se va a despertar y va a buscar en la generación 0 aquellos objetos que ya no sean alcanzables por la aplicación (variables fuera de scope, etc, lo que te contaba antes). La memoria ocupada por esos objetos no alcanzables es desasignada y todo el segmento de esta generación es compactado. Pero los sobrevivientes son inmediatamente movidos al segmento de la generación 1, por esto que te decía que el CLR presume que si zafaron es porque van a vivir un tiempo más. La generación 1 es también recolectada, pero sólo si tratar de liberar memoria en la generación 0 no produjo lo suficiente. Aún así, cuando haya recolección en la generación 1, la memoria de objetos no alcanzables será -nuevamente- desasignada y los que sobrevivan se asumirá que pueden llegar a durar un tiempo más por lo que serán movidos a la generación 2. Podríamos decir "y así sucesivamente" pero no: no hay más generaciones que la 0, la 1 y la 2. La generación 2 tiene la frecuencia de recolección más baja (sólo si recolectar en las generaciones previas no consiguió lo suficiente) y para los objetos que zafan, en esta generación, su memoria es compactada

    Si nuestra aplicación está perdiendo memoria como consecuencia de no soltar todas las referencias a objetos que ya no van a usarse, forzar la llamada al recolector no va a sino agudizar el problema: por un lado, no va a recuperar la memoria de objetos indebidamente alcanzables por lo que la falencia original persistirá; pero aparte va a acortar cambios generacionales innecesaria e improductivamente, con impacto -claro- en el rendmiento general. A esto se le ha dado el curioso nombre de "crisis de los 40" (midlife crisis) o como la canción de Jethro Tull, "demasiado viejo para el rock, demasiado joven para morir". El tema es que la llamada prematura hace que objetos que en cualquier otra circunstancia no hubieran salido de la generación 0, acá terminan en la 1 o la 2 ya que la alta frecuencia de intervención del recolector los soprende todavía "alcanzables" (por ende, por lo que contaba antes, pasan a la generación siguiente). Mover objetos entre generaciones es caro: esos ciclos de CPU los podrían aprovechar hilos efectivos de la aplicación. No debemos olvidar acá que no es sólo cuestión de copiar bytes entre segmentos sino también compactar a los mismos. Todo eso es CPU sólo para una tarea administrativa

    Llamar al recolector en forma explícita mediante GC.Collect() va a correr en el mismo hilo de ejecución en que se estaba ejecutando el método que contiene esta llamada. Por consiguiente, la instrucción siguiente al pedido de recolección no va a ser ejecutada hasta que la recolección finalice

     

     

    Y hay algo aún peor que la "crisis de los 40", en lo que a forzar recolección en escenarios de pérdida se trata: en la medida en que no haya mucho para recolectar, el recolector igual se tuvo que barrer todos los objetos para conocer cuántas referencias alcanzables por dominios de aplicación tenían

    El algoritmo no es trivial: no es cuestión de tener una tabla con referencias porque puede pasar que tengamos una serie de objetos que se referencian circularmente, pero que ese circuito no sea alcanzable; sin embargo cada elemento del grafo tiene al menos alguna referencia. Detectar tales circuitos es parte del cuento (y todo es, nuevamente, CPU)

     

     

    Veamos todo esto en la práctica. Acá tengo la siguiente aplicación: por un lado tenemos una clase que vamos a invocar desde el resto de la aplicación (llamemosla, por ende, Invocado). Invocado se define como sigue

        class Invocado
        {
    // contador de invocaciones a lo largo de la vida de la instancia
    int cantLlamadas = 0; public string[] Invocar() { string[] arregloARetornar = new string[1000]; // se actualiza el contador de invocaciones ++cantLlamadas; for (int i = 0; i < arregloARetornar.Length; i++) { arregloARetornar[i] = "Iteración "+ cantLlamadas+ "; Elemento "+ i; } return arregloARetornar; } }

    Basicamente, tiene un método, Invocado.Invocar(), que crea un arreglo básico de mil cadenas de caracteres y las inicializa a todas con un texto unívoco (conteniendo la invocación general al método y el número de string creado). Este arreglo con todos sus elementos, es devuelto al llamador

    Paremos la película acá: el arreglo creado, con todos sus elementos, es devuelto al llamador

    Lo que el llamador recibe, en verdad, es una referencia al arreglo. Si el llamador, luego de recibirla y procesarla, se deshace de esa referencia, tenemos la plena seguridad de que ese arreglo con todos sus elementos va a quedar disponible para que el recolector de basura lo levante (y, como conté anteriormente, eso va a pasar en la medida en que el recolector pase por la generación en que este objeto ya no referenciado se encuentre: si liberó memoria suficiente en generaciones anteriores, este objeto amigo va a sobrevivir)

     

    La clase que sigue es la que va a llamar a la que vimos recién. Por consiguiente la voy a llamar Invocador. La misma tiene un método, Invocador.Comenzar(), que va a gatillar la creación de una instancia de Invocado, cuyo método Invocado.Invocar() va a ser llamado cien veces

        class Invocador
        { 
            List<String[]> listaResultados = new List<string[]>();
    
            public void Comenzar()
            { 
                Invocado invocado = new Invocado();
    string[] resultados; for (int i = 0; i < 100; i++) { #if RECOLECTANDO GC.Collect(); #endif resultados = invocado.Invocar(); // El arreglo de strings (con todas sus referencias), se enlista // (de modo que no serán elegibles para recolección) listaResultados.Add(resultados); // Recorremos el arreglo resultante haciendo "algo" con sus // elementos (en este caso, mostrarlos por consola) for (int j = 0; j < resultados.Length; j++) { Console.WriteLine(resultados[j]); } } } }

    Lo que es interesante de apreciar en este ejercicio es que Invocador habilita compilación condicional según que queramos forzar recolección de basura. El símbolo condicional es RECOLECTANDO

    Si te fijás en el código, más arriba, por un "presunto" error de diseño las llamadas a Invocado.Invocar() se van acumulando en listaResultados. Cada elemento de listaResultados es un vector de 1000 string por lo cual, mientras listaResultados sea accesible, sus 100 string[] son accesibles y, por cada uno de estos 100 string[], sus 1000 string son accesibles. En otras palabras, como listaResultados va a ser alcanzable durante casi toda la ejecución, sumemos las referencias a 100 string[] (vamos 101 referencias) y 100.000 (cien mil) string. Total: 100.101 (cien mil ciento un) referencias visibles simultáneamente para cuando la aplicación termine

     

    Pues bien, en lo que sigue vamos a comparar dos corridas: ambas perdiendo memoria pero una de ellas dejando que la recolección se dé espontaneamente en tanto que la otra la va a forzar en cada iteración. Para ello me valí de una facilidad de Windows que es el tradicional Monitor de Rendimiento (Performance Monitor). Si no estás familiarizado con el mismo, dejame contarte que es una herramienta súper útil para ver qué pasa con la salud de tu aplicación. Vale 0 (cero, o huevo como dirían en Chile). Es parte del sistema operativo y no sólo tiene varios grupos de parámetros a monitorear sino que además te permite monitorear equipos remotos! Como si fuera poco, vos mismo podés definir tus propios paquetes de parámetros monitoreables. Pero veamos ahora qué pasó con nuestra aplicación, comparando recolección por defecto versus recolección forzada:

     

    # Bytes in all Heaps # Bytes in all Heaps

    Tamaño del montículo de memoria administrada a lo largo de la ejecución (# Bytes in all Heaps)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    A la izquiera tenemos el perfil de ejecución que no fuerza la recolección. Curiosamente, y esto no es que pase siempre sino en este particular caso donde la aplicación pierde memoria, forzar la recolección no hace sino que la aplicación consuma más memoria. Re loco, no? Puede llegar a llevar a la errónea conclusión de que forzar la llamada al recolector hace que siempre una aplicación consuma más pero tampoco es que sea así: esta aplicación, lo sabemos, pierde memoria en la medida en que mantiene "vivas" referencias a objetos no utilizados. Ergo, llamar al recolector para que se haga cargo de una situación en la que poco puede intervenir es como llamar al pintor para que nos pinte una pared que se arruinó por la humedad, sin hacer ningún tratamiento a este último problema

    Llamar al recolector explícitamente no es gratis: si vos lo llamás, claro está, el tipo va a venir y su hilo va a competir por la CPU contra el resto de los hilos del proceso (y, a su vez, el proceso de esta aplicación respecto de sus pares). En el gráfico que viene vas a ver cómo esto se refleja

     

    % Time in GC % Time in GC

    Porcentaje de uso de CPU que se lleva el recolector de basura por sobre el total del CLR (% Time in GC)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    Si te fijás en el gráfico de la derecha, es decir forzando recolección, vas a ver que el share que el recolector se come en la pizza es incrementalmente mayor (el eje horizontal es el tiempo). La explicación de esa participación incremental es que el pobre recolector se tiene que recorrer un número incremental de elementos (aquellos que hacia el final van a totalizar 100.101) sólo para darse cuenta que no hay nada que hacer con ellos porque son alcanzables

    Si miramos, en cambio, qué pasa sin forzar recolección, la intervención del recolector se mantiene moderadamente baja, excepto un peek que se produce casi al final. Y esto se puede ver mejor si contamos, para cada generación, cuántas recolecciones efectivas se llegaron a hacer en las mismas

     

    # Gen x Collections # Gen x Collections

    Cantidad acumulativa de recolecciones en las tres generaciones (# Gen x Collections)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    En la ejecución normal tenemos en total 22 recolecciones de la generación 0, 4 recolecciones de la generación 1 y 2 recolecciones de la generación 2. Forzando recolección de memoria, tenemos 100 recolecciones en las generaciones 0, 1 y 2. Acá está la famosa crisis de los 40 de la que te hablé anteriormente (producto de andar jorobando con recolecciones que hacen que cualquier sobreviviente pase a la generación siguiente, con el consecuente overhead de cambio generacional). Para percibirlo en mejor detalle, te propongo que analicemos los tamaños de los segmentos a lo largo de la ejecución

     

    Gen 0 heap size Gen 0 heap size

    Tamaño del montículo de la Generación 0 (Gen 0 heap size)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    En el caso de la izquierda, sin forzar recolección, tenemos alrededor de 5,5 megas en la generación 0. Esto te da cierta pauta de cuánto llega a medir el montículo de esa generación (un poco más de 6M en este caso). Cuando el montículo creció algo más allá, se quedó sin espacio y el recolector enderezó las cosas mandando sobrevivientes a la generación 1 (y eso, como te contaba antes, pasó 22 veces)

    En cambio, forzando recolección, la generación 0 se mantuvo dentro del 1,5M lo cual -ahora que vimos que el montículo tenía espacio para seguir creciendo arriba de los 6M- nos da la pauta de que lo hemos estado saneando cuando apenas llevaba una cuarta parte de su capacidad ocupada

    Veamos, para entender esto mejor, cómo anduvieron las otras generaciones

     

    Gen 1 heap size Gen 1 heap size

    Tamaño del montículo de la Generación 1 (Gen 1 heap size)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)
     

    He aquí, señoras y señores, la crisis de los 40 reflejada: en la ejecución normal, el tamaño de ese montículo tuvo un gran ascenso hasta que devino su abrupta caída (creció hasta los 4,5M aproximadamente). En esa caída es donde el recolector mandó a la generación 2 a los sobrevivientes. En cambio, en el caso de la recolección forzada, se puede notar que la generación 1 siempre se mantuvo dentro de los 211,5K!! En otras palabras, los objetos entran e inmediatamente se van. Todo ese overhead, claro, se paga con CPU

     

    Gen 2 heap size Gen 2 heap size

    Tamaño del montículo de la Generación 2 (Gen 2 heap size)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    Acá aparece la madre del borrego: la generación 2, en la ejecución normal, viene piola dentro del 1,37M en la medida en que la generación 0 va creciendo, hasta que los sobrantes van pasando a la 1. No te olvides que mientras no se fuerce recolección, el recolector barre una generación primero y, de no haber conseguido memoria suficiente, pasa entonces a la generación siguiente (y así sucesivamente). Por ello la generación 2 pega un gran salto ya en la segunda mitad de la ejecución, cuando es evidente el arrastre de memoria perdida que viene sobreviviendo de las agotadas generaciones anteriores

    En el caso forzado, este segmento viene creciendo lozanamente mientras los otros dos se mantienen por debajo de sus valores de ocupación plena. Al forzar la intervención del recolector de basura no hacemos más que mover bytes entre segmentos, para una ejecución que finalmente terminó consumiendo más. Qué tul?

     

    En fin. Hay otros contadores más de memoria que no utilicé en este caso. Para una descripción total de los mismos te recomiendo que visites el documento "Contadores de Rendimiento de Memoria" en MSDN

    Configurar el Monitor de Rendimiento es realmente fácil. En la figura de abajo te muestro un detalle al elegir para mi propia compu (<Local computer>, porque también podía haber elegido alguna de la red), algunos parámetros medibles de la categoría .NET CLR Memory, filtrando por la instancia del proyecto que tenía abierto en Visual Studio (MemoryLeakProducer.vshost)

    Configurando el Monitor de Rendimiento

    Agregando contadores en el Monitor de Rendimiendo para un proyecto Visual Studio 2008


    Entonces, ahora que eximimos de culpa a la máquina virtual por las pérdidas de memoria y logramos volver a echarnos la culpa -como siempre- a nosotros mismos, veamos a nivel arquitectónico cómo debería usarse y desecharse la memoria

     

    Ciclo de Vida de los Objetos

    En esta era nuestra de la arquitectura de soluciones (solutions architecture), del desacoplamiento (decoupling) y de la separación de intereses (separation of concerns o SoC), es muy posible que el proceso de creación de objetos (junto con la inicialización de sus propiedades, que a su vez puede implicar el crear otros objetos) sea delegado a métodos fabricantes. Estrategias hoy para encapsular esos detalles hay varias, pero por mencionar algunas: fábricas concreta y abstracta e inyección de dependencias (yo mismo escribí hace dos años atrás un artículo sobre Inversión de Control que comentaba cómo fue evolucionando el desacoplamiento en la instanciación y el uso de componentes)

    A simple vista, puede haber un impulso a considerar que la responsabilidad de desasignar objetos les cabe a quienes los crean (es decir, yendo a lo concreto, a las fábricas, inyectores de dependencias, etc). Pero a no equivocarse: como dice el refrán, la culpa no es del chancho sino de quien le da de comer. Si una determina clase C, en algún método M, manda a crear un objeto O a una fábrica F, empieza a verse como claro que es C es la que decide que el objeto sea creado (la fábrica F no lo fabricó espontaneamente sino respondiendo a C en su método M). Podríamos decir entonces que le va cabiendo más a C que a F, desprenderse del objeto

    A la vez, C pudo haber mandado a F a crear el objeto para ponerlo al alcance de un invocador I (aquel que llamó al método M de C). Si en definitiva el objeto se lo va a quedar I, ya no es tan claro que C deba encargarse de desasignarlo (y mucho menos a F!! smile_omg)

    En realidad, dado el siguiente escenario donde un invocador I llama a un método M de una clase C, en donde a su vez se va a pedir a una fábrica F que crée a un objeto O que va a ser retornado a C puede pasar que C haga con él lo siguiente:

    1. Lo guarda en una propiedad P de sí mismo (de C). En ese caso, que sea C quién decida más tarde sobre su destino
    2. Lo devuelve a un invocador I. Vayámonos olvidando de C y F respecto de ese objeto O. La cosa pasa por I o a su vez por quienes dieron intervención a I
    3. Lo asigna a una propiedad P de un argumento A recibido en la llamada a M. Similar al caso anterior: pasa ahora a ser A responsable de deshacerse en algún momento de la referencia (eventualmente cuando la misma A quede desreferenciada)
    4. Lo mantiene en una variable V local al método M. El objeto O va a ser recolectable cuando V pierda visibilidad (a más tardar, al finalizar M)
    5. Lo pasa como argumento a un método M' de una clase C'. En tal caso, de guardar C' una referencia a O, deberá encargarse luego de perderla

    Como se puede ver, el problema del ciclo de vida de los objetos es bastante más complejo que la simplicidad de decir "que el que rompa, después arregle" smile_teeth. A cambio te propongo un enfoque de más alto nivel (por así decir, arquitectónico) para lidiar con este problema. La propuesta es segmentar las instancias de clases según su alcance. A saber:

    • Nivel de Aplicación. Aquellas instancias que, aunque no necesariamente se créen al levantar el proceso de la aplicación (te estoy hablando a nivel de sistema operativo), una vez que surgen, son necesarias hasta que la aplicación sea desmontada
    • Nivel de Sesión. Similar pero usando como timeframe (marco de tiempo) desde que un usuario se logonea hasta que el mismo sale (o su sesión expira). En los tiempos actuales de Arquitecturas Orientadas a Servicio (Service-Oriented Architecture o SOA), el sujeto de la sesión puede ser un usuario o bien un proceso remoto. Normalmente las instancias a nivel de sesión tienen un condicionante (constraint) de privacidad entre sesiones, de modo que sólo puedan ser accedidas por la sesión a la que pertenecen. Esto refuerza la idea de disponer de dichas instancias una vez que la sesión caduca
    • Nivel de Caso de Uso. Dentro de una sesión, a su vez, el usuario o proceso puede iniciar más de un proceso de negocio (comprar pasajes, contratar servicios, ver un resumen de movimientos, etc). Actualmente por cuestiones de experiencia de usuario (user experience o UX) es muy factible que las pantallas que componen el caso de uso se compongan de pasos (en modalidad wizard o asistente) donde el usuario va cargando parte de los datos, y los restantes -en pasos posteriores- van a ser dependientes de los primeros. Es frecuente en estos casos que instanciemos objetos sólo dentro de la vida del caso de uso: sea que el usuario finalice exitosamente o cancelando, los mismos ya no serán menester
    • Nivel de interacción (o actividad, en el caso de workflows). Todavía hilando algo más fino el nivel anterior, especialmente en aplicaciones web o al ejecutar actividades de workflows, existen objetos que se instancian sólo para ejecutar esa particular circunstancia. La vida de estos objetos suele ser muy corta y dependiendo de la carga de trabajo de los servidores que los ejecutan, a veces se suelen reusar para evitar el overhead de crear, liberar instancias mediante la inclusión de un pool de objetos. No obstante, apelar a este tipo de soluciones debería hacerse sólo luego de determinar que el CLR lleva demasiado tiempo creando y liberando objetos

    Un caso extra, no comentado, son los workflows de ejecución prolongada (procesos cuyo lapso total de ejecución podría medirse en horas o días). Normalmente el estado de estos flujos que quedan pendientes de continuación son persistidos para poder ser retomados más tarde. Esa persistencia incluye instancias que van a ser requeridas al retomar (veamos al workflow algo similar al nivel de caso de uso). En la medida en que son persistidas, por ende, pueden ser liberadas

    En la medida en que entandamos estos niveles, podemos organizar nuestras instancias para procurar que sean desasignadas según que el nivel al que pertenezcan caduque. A quién le cabe desasignar instancias? En cada nivel hay un objeto que lleva el control del mismo. Por ejemplo, en el nivel de sesión será un objeto que cumpla el rol de "administrador de sesiones" (que es quien acusa recibo de un usuario que se desloguea o que una sesión expiró). A ese objeto no le cabe directamente la desasignación de todos los objetos de ese nivel, pero sí el gatillarla

    Algo muy piola, para cualquier nivel pero lo ejemplifico con el nivel de caso de uso, es que si todos los objetos de este nivel son alcanzables pura y exclusivamente desde un objeto general (creado para la ejecución del caso de uso), al deshacernos de este objeto general (dejar de referenciarlo) ya no habrá más forma de alcanzar al resto de las instancias del nivel. Si te fijás, a nivel de sesión, esta estrategia es la que usa ASP.NET con su objeto Session. Bueno, así es justamente como ASP.NET procura que no le queden instancias colgadas dentro del rango de una sesión si la sesión en que se crearon expiró

     

    En una segunda derivada de este análisis, el control de instancias mediante la alineación a de las mismas al nivel correspondiente según su ciclo de vida como objeto se complementa con el control referencial. Tanto en Java como en .NET, una variable o propiedad de una clase declaradas de determinado tipo T no primitivo (es decir, no entero, flotante, booleano, etc) no guardan el contenido de ese tipo, sino una referencia (sí, exacto: un puntero a memoria) a otro objeto del tipo en cuestión

    En nuestro ejemplo de arriba, la clase Invocador tiene un miembro llamado listaResultados de tipo List<string>. Pues bien, listaResultados no contiene tal lista sino que listaResultados es un puntero a otro objeto en memoria que sí contendra esa data. Las ventajas del código administrado (managed code) es que nosotros ni debemos concientizarnos de que son todos punteros: el entorno de ejecución administrado se encarga de todo eso

    La realidad es que si declarásemos una variable v del mismo tipo que listaResultados y le asignásemos listaResultados, lo que se asigna es el puntero. Como consecuencia, no van a quedar dos copias en memoria sino que cualquier alteración al objeto de tipo List<string> refenciado por listaResultados, va a ser percibible accediento al objeto desde v (y viceversa). En otras palabras, listaResultados y v hacen referencia al mismo objeto

    Si en un momento dado listaResultados desaparece (por ejemplo, porque su objeto contenedor Invocador fue levantado por el recolector de basura, el objeto de tipo  List<string> apuntado por listaResultados aún no es pasible de ser recolectado porque... al menos la variable v (si no otros punteros también) todavía lo están referenciando  

    Control de referencias o control referencial, entonces, complementa al control de instancias en la medida que asegura que si un objeto O pertenece a determinado nivel N, cualquier referencia al objeto (sea una propiedad en una clase, sea una variable de programa, sea un argumento de un método aún en ejecución, o cualquier otro puntero) no va a durar más allá de ese nivel. De hacerlo, de trascender al nivel al que pertenece, el objeto O también va a trascender ese nivel y el recolector de basura no va a poder llevárselo en la medida en que aún esté siendo referenciado por otras variables u objetos alcanzables

     

     

     

    Volviendo al caso de la aplicación que pierde memoria, veamos estos conceptos de control de instancias y control referencial en la práctica

    Nuestra aplicación estaba innecesariamente, al enlistar resultados en listaResultados, otogando a los mismos "nivel de aplicación" ya que listaResultados es un miembro de la clase Invocador que se crea al iniciarse la ejecución y se desasigna al finalizar. Por ende, primera medida en este ejemplo, chau listaResultados

        class Invocador
        { 
            public void Comenzar()
            { 
                Invocado invocado = new Invocado();
    string[] resultados; for (int i = 0; i < 100; i++) { resultados = invocado.Invocar(); // Recorremos el arreglo resultante haciendo "algo" con sus // elementos (en este caso, mostrarlos por consola) for (int j = 0; j < resultados.Length; j++) { Console.WriteLine(resultados[j]); } } } }

    Optimización I - Aplicando Control de Instancias, la serie de resultados deja de tener nivel de aplicación

     

    Ahora vamos a repasar resultados de la ejecución con esta primera optimización pero aún antes de seguir tenemos otra disponible: si te fijás, en el último loop (aquel que despliega por consola los resultados), una vez que ejecutamos una iteración j, el elemento de dicha iteración (resultados[j]) ya no va a ser accedido en el resto de este ejemplo. Aplicando control referencial, entonces, qué pasa si lo desasignamos "in situ"? Tan sólo se necesita asignarle null a dicha entrada para que deje de referencias al string como lo venía haciendo. Con esto, aunque éste es un ejemplo trivial, le estamos dando a cada entrada de resultados un nivel similar al de interacción (en el sentido de una vida resumida a la máxima brevedad posible)

    Entonces, con esta nueva optimización, nos queda

        class Invocador
        { 
            public void Comenzar()
            { 
                Invocado invocado = new Invocado();
    string[] resultados; for (int i = 0; i < 100; i++) { resultados = invocado.Invocar(); // Recorremos el arreglo resultante haciendo "algo" con sus // elementos (en este caso, mostrarlos por consola) for (int j = 0; j < resultados.Length; j++) { Console.WriteLine(resultados[j]); resultados[j] = null;
    } } } }

    Optimización II - Como consecuencia de un Control Referencial, cada entrada en resultados es desasignada cuando ya no se va a usar

     

    Vamos a comparar las dos ejecuciones:

     

    # Bytes in all Heaps # Bytes in all Heaps

    Tamaño del montículo de memoria administrada a lo largo de la ejecución (# Bytes in all Heaps)
    A la izquierda, sólo aplicando Control de Instancias. A la derecha, Control de Instancias y además Referencial (hacé click en las imágenes para verlas mejor)

    En primer lugar, tuve que cambiar el factor de escala para poder mostrar los gráficos. Si en las corridas del principio, perdiendo memoria, estaba hablando de un promedio de memoria reservada alrededor de los 2M (y un máximo en torno a los 9M), acá hablamos de un promedio inferior a los 200K (y un máximo debajo del mega)

     

    % Time in GC % Time in GC

    Porcentaje de uso de CPU que se lleva el recolector de basura por sobre el total del CLR (% Time in GC)
    A la izquierda, sólo aplicando Control de Instancias. A la derecha, Control de Instancias y además Referencial (hacé click en las imágenes para verlas mejor)

    Un segundo beneficio que nos llevamos, al evitar pérdida de memoria mediante la correcta alineación de instancias de objetos a un nivel acorde a su ciclo de vida es que el recolector de basura no sólo va a hacer mejor su tarea de liberar memoria: la va a hacer más rápido!! La razón? Al encontrar instancias que sí deben liberarse, nuestro amigo va a evitar volver a toparse con ellas una y otra vez en sus futuras intervenciones. Nada de pasar a generación 1 o 2: arrivederci (como debe ser)

    Vale la pena destacar que en el caso II (a la derecha), con la máxima optimización, el recolector intervino la mitad del tiempo que aplicando sólo la optimización I (izquierda)

     

    # Gen x Collections # Gen x Collections

    Cantidad acumulativa de recolecciones en las tres generaciones (# Gen x Collections)
    A la izquierda, sólo aplicando Control de Instancias. A la derecha, Control de Instancias y además Referencial (hacé click en las imágenes para verlas mejor)

    Lo primero que quiero hacerte notar es que en ambos casos no llegó a haber recolección en la generación 2. En otras palabras, incluso la optimización I alcanzó para que las intervenciones del recolector sean efectivas en las generaciones bajas. Las recolecciones de la optimización I solamente se repartieron así: 21 en la generación 0 y 6 en la 1. Aplicando además la optimización II, en cambio, hubo 27 recolecciones en la generación 0 y 3 en la 1 (más allá de que el número de recolecciones es mayor, la duración de las mismas fue eficientemente bajo -como te contaba antes, la mitad que lo que demoró el caso que sólo aplicó optimización I-)

     

    Gen x heap size Gen x heap size

    Tamaño de los montículos de la tres geeneraciones (Gen x heap size)
    A la izquierda, sólo aplicando Control de Instancias. A la derecha, Control de Instancias y además Referencial (hacé click en las imágenes para verlas mejor)

    Decidí optimizar aquí en un sólo gráfico las tres generaciones. A la izquierda (aplicando sólo optimización I) vemos que la generación 0 se mantiene alrededor de los 2,5M (con tres evidentes peek donde supera los 4M). Esto es menos de la mitad del tamaño que alcanzó en el esquema con pérdida de memoria. Pero la cosa es todavía mejor aplicando además la optimización II (a la derecha): entonces la generación 0 se mantuvo alrededor del mega. Con pequeños saltos hasta 1,5M. Sweet! heart

    La generación 1 se mantuvo oscilando alrededor de los 240K para la optimización I y, menos aún, 135K si añadimos aparte la optimización II (en las gráficas, es una muy chata línea celeste que se ve casi al 0 del diagrama)

    La generación 2, en ambos casos, se amesetó en los 118K y ya no bajó de allí por el hecho de que nunca llegó a haber recolección en la misma (en los diagramas es imperceptible). Pensá que en el ejemplo inicial, con pérdida de memoria, estuvo un buen rato dentro del 1,37M hasta que se disparaba a los 6M y más

     

    Por sobre todo, creo haber dejado con estas dos optimizaciones, más que claro que enfrentar el problema de "la gotera" de memoria es definitivamente más efectivo que forzar la supérflua intervención del recolector de basura. Pasemos ahora a ver cómo se enfrenta el problema de "la gotera"

     

    Detectando Leaks: el CLRProfiler

    El ejemplo que hemos usado en esta aplicación es trivial y muy ad hoc para mostrar rápidamente cómo tocando algo cambia copernicanamente la situación. Pero en las aplicaciones que a vos y a mí nos tocan mantener, la cantidad de clases son infernales, y aún muchás más sus instancias de objetos por lo que más allá de los indicios que a priori puedas tener... la verdad es que podés estar días buscando la causa. Si tu aplicación está en producción hablar de "días" en lugar de "horas" para resolver un problema es un lujo que no te vas a poder dar

    Para esto existe una herramienta que te permite perfilar el comportamiento del CLR durante la ejecución (memoria consumida, tiempo de vida según tipos de datos, etc). Me refiero al CLRProfiler. Esta facilidad, como el Monitor de Rendimiento, también está disponible en forma gratuita aunque en este caso no viene incluído como parte del sistema operativo sino que se descarga de la web de Microsoft (la URL es http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&DisplayLang=en)

    Para el ejemplo de esta aplicación, perfilé la ejecución de la versión inicial, con pérdida de memoria, recibiendo estos resultados:

     

    Histograma por edad

    Un histograma según la "edad" de los objetos me muestra que un considerable número de megas ocupados durante lapsos que superan los 20, 30 y más segundos pertenece a objetos de la clase string (en rojo en el histograma)

    Que más del 90% de los objetos creados correspondan a string ya nos puede dar indicios de por donde empezar el control de instancias. Que, aparte, varios de estos tengan una vida tan prolongada, nos da la pauta de que podríamos tener que aplicar optimización referencial

    Entonces nos preguntamos, y estos string dónde es que se originan? Revisemos el grafo de asignación de memoria que nos tira CLRProfiler:

     

    Grafo de alocación

    Y acá siguen apareciendo elefantes: el método Invocado.Invocar() se lleva un 75.27%, esto es, las tres cuartas partes de la allocación total de memoria. Como vimos antes, eso no quiere decir que él deba allocar menos sino que es acá donde se origina el grueso. Pero luego nos resta ver a nosotros dónde se debería desasignar esa memoria. Por ahora, completemos lo que vinimos a buscar: en este caso, que indirectamente, Invocado.Invocar() termina generando la creación de string por un total equivalente al 42% de la memoria total. Estos string que, como veíamos, duraban en algunos casos arriba de los 30, 40 segundos

     

    Entonces, con estos elementos, sí nos mandamos a la aplicación a revisar quiénes están llamando a Invocado.Invocar() y qué hacen con lo que este método devuelve. Para dejar constancia, luego de aplicar las dos optimizaciones que te mostré antes, basándome en la regla de los niveles según ciclo de vida, volví a perfilar la aplicación y el histograma me mostró lo siguiente

     

    Histograma por edad

    La mayoría de los string ahora muere en menos de 10 segundos (antes era todo lo contrario). Se ve?

    Moraleja de este post: si una aplicación consume mucha memoria, no es cuestión de forzarla a que instancie menos objetos que los necesarios sino de asegurarse que estos sean recolectados cuando ya no se necesiten

     

     

    Algo así como acordarse de sacar siempre la basura a las 8 de la noche Wink (o de la tarde, si estais en España, jo'er!). Estamos aplicando acá Pensamiento Lateral (Lateral Thinking) 

     

    Bueno, me voy despidiendo acá pero te dejo algunas referencias interesantes para seguir explorando:

    January 10

    Un Día Raro (A Strange Day) - The Cure

    The Cure logra eso de narrar una situación angustiante en una forma que parezca un momento pleno de felicidad. Como si el peor final sea incluso la mejor manera de, aunque sea, terminar de una vez y rajarse para siempre (y ni siquiera dar vuelta la página: cerrar la contratapa). Esto de sentir pasión por una Naturaleza agresiva, revelada, movilizada contra uno no es nuevo: el Romanticismo en todas sus manifestaciones (musical, visual a través de pinturas y fundamentalmente literaria a través de poesías y narraciones) suele contraponer el estado de la Naturaleza al estado de ánimo. Así, una situación de alegría va siempre junta a un cielo tormentoso u otro tipo de tempestad. Como contrapartida, un momento de tristeza incontenible va de la mano de un cielo azul profundo y un sol que todo lo ilumina

    En las letras de The Cure se percibe así un existencialismo romántico. El protagonista en primera persona de esta banda (rol impregnado fuertemente por la personalidad excluyente de Robert Smith) suele dejar de manifiesto a lo largo de todas las canciones un cuestionamiento a su propia existencia, a menudo previendo no sin excitación una discontinuidad inmediata. Cuando leas la letra que paso más abajo (con tablaturas para una o dos guitarras) estimo que no te van a quedar dudas de esto que te digo, y que se repite a lo largo de varios hits de la banda (como Lullaby o Close to me -este último, con el grupo exultante ya que el ropero en donde amanecieron encerrados se cayó a un lago y se está llenando de agua; en Lullaby, se le mete una araña en la habitación y se lo lastra -engulle-). En fin... 

    The Cure es no el único pero sí uno de los principales exponentes de toda la historia del dark rock (rock oscuro, una corriente post-punk también conocida como género gótico). Seguramente no el único, pero sí con una personalidad fuertemente marcada que le han permitido no sólo diferenciarse del resto, sino principalmente durar: The Cure es una de las pocas bandas de los '80 aún en pie -más allá de rumores de separación que datan desde la misma formación del grupo a fines de los '70 y frecuentes cambios en los integrantes, nunca han transcurrido cinco años completos sin que saquen un disco de estudio-. Si bien se puede mencionar a U2 como otro que también duró y que es de hecho más popular que The Cure (por lejos, huelga decirlo), U2 cambió radicalmente su estilo: de ser en sus orígenes un grupo de protesta, presenta hoy una cosmética completamente pop (y frívola, huelga decirlo nuevamente). En ese sentido The Cure, si bien debe su fama y reconocimiento por parte de la audiencia masiva a una serie de hits pop que ha ido incluyendo en todos sus trabajos, nunca abandonó esa escencia oscura que fue su sello original

    En la canción que sigue a continuación, "Un Día Raro", el mar de una playa de piedra (referenciado como un ciego arrodillado) va a crecer y a tragarse a nuestro personaje que aparentemente -por cierto comentario de paredes que chocan- estaba en un barco. La canción cumplió sus bodas de plata durante el año que terminó, 2007 (para ponerlo en perspectiva, en 1982 Smith no tenía aún los 25 años de vida que hoy ya superó esta canción). No obstante la completo con una versión en video relativamente reciente: año 2003, Berlín (Alemania). Para esa ocasión The Cure tocó en vivo durante dos noches tres álbums completos de su extensa discografía. Muy en contraste con su visita a la Argentina en 1987, cuando las dos funciones que ofrecieron tuvieron que ser abruptamente suspendidas a causa del desborde del público. Esta canción, curiosamente, fue de las pocas que se llegaron a salvar y así haberse ofrecido en forma completa y sin interrupciones

    En el video de Berlín 2003 vas a ver a un The Cure definitivamente logrado: desplegando madurez sin por ello perder espontaneidad. Destaca sobre todo el bajo de Simon Gallup (claramente lo que me decidió a poner esta versión en lugar de la de Orange, Francia, de 1986)

    "Un Día Raro" aunque, tratándose de The Cure, apenas si un día más

     

    Acordes: EADGBE     EADGBE     E A  D  GBE
          Am 577555   F 133211   C 8-10-10-988
          Bm 799777  Em 022000   E 0 2  2  100
           G 355433   D 557775

    Base: Am Bm G

    Am           Bm                 G
    Give me your eyes that I might see Dame tus ojos que puede ser que vea
    Am            Bm                G
    the blind man kissing my hands al ciego besarme las manos (N. del T.: el mar y la playa en gral.)
    Am               Bm                     G
      The sun is humming, my head turns to dust El sol tararea, mi cabeza apunta hacia el polvo
    Am        Bm                      G
      as he plays on his knees cuando él juega arrodillado
    as he plays on his knees cuando él juega arrodillado
     
    F
    And the sand and the sea grow La arena y el mar crecen
        G
    I close my eyes Yo cierro los ojos
    F
    Move slowly through drowning waves Me muevo despacio por olas que me ahogan
    G
    going away on a strange day al salir de un día raro


    E |-----0-1-3-3-3-1-1-0---3-3-1---0-1-3-3-3-1-1-0-1-0-----------0-0-1-0---------------------3-1-0-|
    B |-3-3-----------------3-------3---------------------3-1-0-1-3---------3-1-0-1-0-----------------|
    G |-------------------------------------------------------------------------------2-0-0-0-0-------|
    D |---------2-----------4-------------------------2-----------------4-----------------------------|
    A |---------0-----------2-------2-----------------0-----------------2---------------2-------------|
    E |-----------------------------3---------------------------------------------------3-------------|

     
     

    Am                 Bm                 G
    And I laugh as I drift in the wind Y me río mientras el viento me deriva
    Am                   Bm               G
    blind, Dancing on a beach of stone ciego, de un lado al otro en una playa de piedra
    Am                         Bm                 G
    Cherish the faces as they wait for the end Acaricio las caras que esperan el final
    Am        Bm               G
      Sudden hush, across the water De golpe silencio, en toda el agua
    And we're here again Y estamos acá de nuevo
     
    F
    And the sand and the sea grow La arena y el mar crecen
        G
    I close my eyes Yo cierro los ojos
    F
    Move slowly through drowning waves Me muevo despacio por olas que me ahogan
    G
    going away on a strange day al salir de un día raro
       
    Em                                        F
      My head falls back and the walls crash down La cabeza se me va para atrás y las paredes chocan
    G                                  Am
    and the sky and the impossible explode y el cielo y lo imposible explotan
    Bm                                  C
      Held for one moment I remember a song Contenido por un instante me acuerdo de una canción
    D
    An impression of sound Una impresión del sonido
             Em                    E
    and then everything is gone forever y entonces todo se acabó para siempre

    E |-----0-1-3-3-3-1-1-0---3-3-1---0-1-3-3-3-1-1-0-1-0-----------0-0-1-0---------------------3-1-0-|
    B |-3-3-----------------3-------3---------------------3-1-0-1-3---------3-1-0-1-0-----------------|
    G |-------------------------------------------------------------------------------2-0-0-0-0-------|
    D |-----------------------------------------------------------------------------------------------|
    A |-----------------------------------------------------------------------------------------------|
    E |-----------------------------------------------------------------------------------------------|

     
    E |-3-3-3-1-1-0---3-3-1---0-1-3-3-3-1-1-0-1-0-----------0-0-1-0---------------------3-1-0-|
    B |-------------3-------3---------------------3-1-0-1-3---------3-1-0-1-0-----------------|
    G |-----------------------------------------------------------------------2-0-0-0-0-------|
    D |-2-----------4-------------------------2-----------------4-----------------------------|
    A |-0-----------2-------2-----------------0-----------------2---------------2-------------|
    E |---------------------3---------------------------------------------------3-------------|

      
       
         Am       Bm        G
    A strange (...ange) (...ange) day Un día raro
         Am       Bm        G
    A strange (...ange) (...ange) day Un día raro


    E |-----0-1-3-3-3-1-1-0---3-3-1---0-1-3-3-3-1-1-0-1-0-----------0-0-1-0---------------------3-1-0-|
    B |-3-3-----------------3-------3---------------------3-1-0-1-3---------3-1-0-1-0-----------------|
    G |-------------------------------------------------------------------------------2-0-0-0-0-------|
    D |---------2-----------4-------------------------2-----------------4-----------------------------|
    A |---------0-----------2-------5-----------------0-----------------2---------------5-------------|
    E |-----------------------------3---------------------------------------------------3-------------|

    E |-3-3-1-0-3-3-1-0-3-3-1-0---0-1-1-0-----------0-0-1-0---------------|
    B |-------------------------3---------3-1-0-1-3---------3-1-0-1-0-----|
    G |---------------------------------------------------------------2-0-|
    D |-2-------4---------------------2-----------------4-----------------|
    A |-0-------2-------2-------------0-----------------2-------------2---|
    E |-----------------3---------------------------------------------3---|


            

    January 05

    Llegan los Reyes: Sesiones Completas del Foro de Arquitectura de Microsoft Corp

    clip_image002

     El  pasado Noviembre se realizó el Foro Anual de Arquitectura en el Centro de Convenciones de Microsoft. Este tipo de eventos es bastante diferente, si lo comparamos, al track de Arquitectura que se incluye en la conferencia TechEd de desarrollo de software. Es sabido que, en nuestra industria, el término "arquitecto" es tomado con mucha amplitud y dependiendo del contexto hace referencia a roles de diferente seniority. Podríamos decir que el estilo de arquitecto que asiste a este foro es más bien aquel que está más allá de una aplicación específica, pero que está en todas al mismo tiempo en la medida en que entiende cómo éstas se organizan para soportar el famoso "negocio" que su organización lleva adelante

    Por tal motivo, las sesiones de este foro hacen mucho hincapié en lo que viene en cuanto al aprovechamiento que toda organización pueda hacer de ellos en términos de su relación con clientes, proveedores, socios comerciales y, finalmente, sus propios procesos internos de TI (control de cambios, ciclo de vida, etc). En ese sentido, no esperes acá ver grándes demos de cómo se configura tal cosa para habilitar REST en lugar de SOAP, etc sino más bien por qué REST y no SOAP o viceversa

    Para marcar otra diferencia con TechEd, esta conferencia no es de entrada libre al público sino que es por invitación de Microsoft a sus clientes. Por tal razón, los asistentes son sólo un selecto grupo. Como contrapartida, lo bueno es que lo que se muestra acá -como vas a ver ahora- luego es publicado en forma completa. En el caso de TechEd, sólo si la organización del TechEd así lo dispone (y, al menos la última vez, se dispuso que no smile_sad)

    El pueblo quiere saber de qué se trata

    Día 1

    Ver Sesión

    PPT

    Cambiar el Mundo con Software y Servicios
    Donald Ferguson comienza listando las tendencias actuales derivadas de los últimos adelantos en tecnología que, innegablemente, cambian cada vez más nuestra vida y la forma de consumir cosas u obtener información. Entonces plantea el típico escenario de una compañía hipotética que agrega valor a sus procesos mediante el consumo de servicios provistos por terceras partes, analizando el impacto tanto para dicha compañía como para el proveedor de ese servicio e incluso ya para aquellos terceros que quieran -a su vez-, agregar valor a sus procesos consumiendo ya no los servicios del tercero original sino los de la compañía tomada como centro de la hipótesis
    En concreto, SOA ya no está sólo en este mundo de servicios: los mashups y las RIAs (aplicaciones basadas en Internet que aprovechan a full recursos del dispositivo en que se ejecutan) son hoy parte del ecosistema

    video

    presentacion

    Anatomía de una Aplicación Software + Services
    Eugenio Pace (ex Patterns and Practices donde dirigió el Composite Application Block y la derivada Smart Client Software Factory que hoy sigue llevando adelante Glenn Block) baja algo más a la tierra las ideas del keynote de Ferguson, explicando con admirable precisión el ecosistema S+S donde unos consumen servicios, otros los desarrollan y unos terceros los ejecutan (percibiendo así su parte de la pizza). Eugenio luego presenta un pantallazo de lo que Microsoft está ofreciendo hoy en su estrategia S+S, con servicios fundacionales (por ejemplo para identificación o para video streaming), otros agregables por suscripción (como OneCare o XBOX Live) y servicios de rango superior (ejemplos tales como Office Live, Windows Live o Dynamics CRM)

    video

    presentacion

    REST: un Enfoque Liviano, Orientado a Datos para el Software Concurrente y Distribuido en Empresas
    George Chrysanthakopoulos, investigador en Microsoft Research, nos muestra un pantallazo de Microsoft Robotics Studio: un kit de aplicación de conceptos como orientación a servicios pero para aplicaciones que incorporen robótica (una introducción decente a Microsoft Robotics Studio está disponible acá). A lo largo de su charla, el presentador nos va a mostrar -en los papeles y en la práctica- el modelo descentralizado de aplicación para servicios de software (DSS) y el motor de ejecución para concurrencia y coordinación, que permite orquestar señales asíncronas con simplicidad como horizonte. El modelo de programación no es C++ ni nada sólo para una elite: toda la plataforma Robotics es .NET

    video

    presentacion

    Levantando las Barreras para la Voz por IP (VoIP)
    Gurdeep Pall (ex miembro del equipo de Arquitectura que integro y actual vicepresidente corporativo de Microsoft para el grupo de Comunicaciones Unificadas) ofrece una sesión muy interesante sobre un aspecto que hoy las organizaciones vislumbran como uno de los peores enemigos de la productividad: la sobrecarga derivada de las facilidades que hoy las comunicaciones ofrecen (dicho en otras palabras, el tiempo que hoy los empleados independientemente del rango dedican a ver y responder correos, asistir a reuniones y otros esquemas de comunicación). Gurdeep se propone mostrar una plataforma novedosa, MS Unified Communications, que surge como una forma de responder a las siguientes preguntas: cómo priorizar comunicaciones para poder reaccionar en una forma más productiva? cómo aprovechar la infraestructura existente en conjunto con Internet para abaratar los costos de las comunicaciones? cómo integrar toda la plataforma (telefonía fija, celular, la red de computadoras, etc?). Como cierre, vas a poder conocer la interfaz de voz del Outlook (si no la conociste ya)

    video

    presentacion

    Proyecto Astoria: Servicios de Datos para la Web
    Pablo Castro, del equipo ADO.NET nos da un pantallazo de hacia dónde esta API de acceso a datos va a extender sus dominios (estimativamente, hacia mediados de año). Astoria es un framework para poder consumir información tanto dentro de la empresa como hacia afuera, basándola en los protocolos REST de la Web 2.0 (ATOM, JSON). La idea de esto es que las organizaciones puedan poner su información disponible para clientes HTML, Silverlight, mashups o clientes de escritorio que sean capaces de consumir datos en estos formatos

    video

    presentacion

    Arquitectura de Aplicaciones Compuesta Usando 2007 Office System
    Con probablemente una de las sesiones que más te voy a recomendar, Scott Jamison repitió acá el éxito que logró en el track de Arquitectura del pasado TechEd, cuando alcanzó el mejor score como orador en una sesión similar. Normalmente venía produciendo cierto rechazo la sola mención de Office 2007 o específicamente Sharepoint 2007 en una charla de arquitectura (en parte aventados por los dolores de cabeza ocasionados por las versiones anteriores de este último), en tanto que era recibido como un "sales pitch" (una venta, basicamente hablando) de un producto Microsoft. Hoy podemos decir ya que cierta agua ha corrido bajo el puente, y algunos resultados tangibles se empiezan a notar. En esta sesión vas a ver ejemplos concretos -y de arquitectura- en los cuales los beneficios de aplicar Sharepoint como columna vertebral de una aplicación que se compone de cachitos de aplicaciones existentes saltan a la vista. La calidad técnica de esta sesión es especialmente notable

    video

    presentacion

    Día 2

    Ver Sesión

    PPT

    Amazon.com: Simple Storage Service (S3), Elastic Compute Cloud (EC2) y Simple Queue Service (SQS)
    Charlie Bell, vicepresidente de Tecnología en Amazon Web Services, nos sorprende contándonos cómo las necesidades de evolución de la aplicación de Amazón dieron lugar a una serie de servicios que, si bien originalmente se habían concebido para poder mantener el portal en funcionamiento, son hoy una fuente de ingresos para esa compañía ya que los vende a terceros. Una historia impresionantemente Web 2.0 que bien podría mañana tenerte a vos como protagonista

    video

    presentacion

    Viaje al Centro de Microsoft Research
    Behrooz Chitsaz nos ofrece un panorama de la usina de investigación de Microsoft, cómo ha ido creciendo e instalándose en países tan diversos como China, Israel o la India, cómo colabora con universidades (a la vez que se nutre de ellas) y -por sobre todo- unas interesantes demos de reconocimiento de lenguaje natural, análisis de redes de datos, reconocimiento facial, biología computacional y más. Vale la pena tener en cuenta que de este laboratorio han salido la TabletPC (con su reconocimiento de letra escrita), el buscador de escritorio, el chequeo de sintaxis del Office o la próxima mesa programable Microsoft Surface, entre varios otros logros

    video

    presentacion

    Una Capa de Identificación Basada en Reclamos para la "Nueva Internet"
    Es sabido que el manejo de identificaciones en Internet ha ido evolucionando por mecanismos dispares al compás en que los usos de Internet también evolucionaban. Hoy usamos la internet como mecanismo de transporte no sólo para que personas consuman servicios sino para que procesos hagan lo mismo. A esta altura poder manejar un modelo unificado de identificación parece quimérico. Y sin embargo es lograble, como lo va a demostrar Slava Kavsan en esta sesión

    video

    presentacion

    Duet: Software Más Servicios de la Mano de Microsoft y SAP
    Para quienes no lo conocen, Duet es una forma de enlazar aplicaciones SAP con una fachada más familiar e integrada a través de las aplicaciones Office tradicionales. Lo que me pareció más valuable de esta sesión -si bien yo no me dedico a temas de CRM- fue la interesante discusión de problemas de arquitectura que han ido surgiendo a lo largo de la evolución de esto que originalmente apareció como "Proyecto Mendocino", y cómo se han ido resolviendo. La sesión fue ofrecida por Chris Keyser y Burra Gopal por parte de Microsoft, y Adi Kavaler por parte de SAP

    video

    presentacion

    El Futuro del Datacenter (I)
    Debra Chrapaty nos cuenta cómo Microsoft está planificando sus datacenters para hacer frente al escenario consolidado de software más servicios. Enterate de las distintas estrategias que están evolucionando para ofrecer alta disponibilidad y confiabilidad de lo que las aplicaciones esperan encontrar "allá en la nube"

    video

    presentacion

    El Futuro del Datacenter (II)
    John Dwyer ofrece otra perspectiva respecto de como los datacenters están evolucionando. Esta vez el enfoque tiene que ver con la creciente consolidación de los mismos y la demanda energética que se avizora, en conjunto con regulaciones necesarias para mantener nuestro medio ambiente verde (o mejor dicho, volverlo a ver verde algún día y no negro azabache como va camino a). Esta sesión es del paladar de los arquitectos de Infraestructura

    video

    presentacion

    Experiencia de Usuario en la Plataforma Windows Live
    La historia que David Dumler y Angus Logan nos cuentan acá es en cierto modo similar a la de Amazon que te mostré más arriba, sólo que esta historia aún está evolucionando. Enterate cómo Windows Live ha ido madurando una serie de servicios de diferente granularidad, con la idea de poder lograr en el futuro próximo una plataforma disponible por todos para montar aplicaciones que maximicen experiencias de usuario inmersivas y personalizadas, disponibles en toda "la red", y aprovechables tanto por personas como por organizaciones que quieran ganar nuevos clientes y hacer crecer su facturación

    video

    presentacion

    Experiencia de Usuario para Arquitectos
    Simon Guest propone acá dejar por un rato de lado el debate de los datacenters, la orientación a servicios y los workflows para concentrarnos aunque sea por un rato en las necesidades del usuario final. Para ello nos va a presentar un esquema de trabajo en el cual los arquitectos de software se pueden basar para pensar la capa de interacción centrada en la idea de que quienes vayan luego a usarla no deban, por ello, sufrirla

    video

    presentacion

    Microsoft IT: Viaje al Centro de la Cocina de Microsoft
    Si Microsoft dice proveer herramientas de TI que permiten a los negocios evolucionar y crecer... Cómo la lleva Microsoft con todo eso? Será como la vende o será más bien un enfoque "casa de herrero, cuchillo de palo"? Neil Leslie y Barry Briggs responden la pregunta y te cuentan mucho más acerca de cuánto de lo que Microsoft vende, surgió inicialmente como iniciativa interna. Seguramente que el componente "suerte" existió en la historia de Microsoft (como también lo habrá habido en el caso Amazon y en cambio faltó en la recientemente desaparecida Netscape), pero esta sesión -como aquella de Amazon- se encarga de mostrar que no todo es casualidad

    video

    presentacion

    Día 3

    Ver Sesión

    PPT

    MySpace: Lecciones Aprendidas al Filo de la Web
    Cuando Aber Whitcomb fundó MySpace junto con otros amigos, pensaron que un modelo de trabajo reactivo (on demmand) era suficiente: si algo se rompía, se arreglaba y punto. Al principio ese modelo funcionó pero inmediatamente Aber y los suyos empezaron a notar cómo estaban dejando pasar oportunidades. Mirá está sesión y conocé cómo cambiando a un esquema proactivo primero y estratégico después, MySpace es hoy uno de los sitios de la llamada "web social" de mayor tráfico, ofreciendo una serie de servicios distribuidos altamente disponibles. La paradoja de lo importante que es saber cambiar a tiempo si se quiere seguir igual

    video

    presentacion

    Manual para Conducir a los que Desarrollan Software
    Paul Glen es un consultor que hace un tiempo atrás sacó un libro acerca de cómo liderar equipos de desarrollo de software. Esta presentación es interesante en la medida en que este tipo de equipos de trabajo suele tener particularidades propias que no están presentes en otros tipos de industria. Es una realidad que los desarrolladores suelen ser más leales a la tecnología que les gusta que a vos que sos su jefe y tratás de hacerles entender que "en este proyecto no la podemos usar". Glen habla de este y otros temas que suelen impactar en los aspectos emocionales de quienes desarrollan software, y a la larga determinan el éxito o fracaso de los proyectos

    video

    presentacion

     

    Hacía rato que veníamos necesitando una sorpresa así. Después de tantos años de mishiadura yo ya había dejado de poner los zapatitos porque pasaban los reyes y me los afanaban

    December 05

    Para Poner en el Arbolito: el Architecture Journal Reader (Beta)

    Platform Architecture Team

     Arrimándose  las fiestas y otro año que pasa volando, los del Equipo de Arquitectura de Plataforma Microsoft te queremos acercar la beta de una aplicación que esperamos te resulte piola

    El Architecture Journal Reader es una facilidad que te va a permitir recibir en línea la revista homónima (The Architecture Journal), que por si no la conocías, es una publicación trimestral que dirije Simon Guest. The Architecture Journal es traducido a varios idiomas, aunque ésa no es una actividad que hacemos nosotros sino que determinadas subsidiarias de Microsoft, según el presupuesto, etc, traducen ciertos números a idiomas locales. La edición en español está disponible a partir del número 3 (desconozco la razón por la cual nunca se tradujeron los números 1 y 2 porque -como contaba- no pasa por mí traducirlo)

    El contenido de la revista, contrariamente a lo que puedas pensar, no es exclusivamente centrado en tecnologías Microsoft sino en tendencias de la industria (aplicaciones compuestas, SOA, Web 2.0, etc). De hecho la mayoría de los artículos de cada edición son contribuciones externas de arquitectos. Sí, quise decir eso: vos mismo podrías ser un contribuyente del Journal y sumarte un poroto ante tus pares. El call for papers se publica en un RSS feed suscribible acá: http://msdn.microsoft.com/architecture/arcJournal/rssCallForPapers.xml

    Para contenido específicamente Microsoft te recomiendo que visites el portal de Arquitectura MSDN

    El Architecture Journal Reader se instala localmente en tu PC y cada vez que lo abrís se sincroniza con nuestros servidores para descargar -dado el caso- las novedades disponibles. Y con esto no nos referimos exclusivamente a artículos: el Reader tiene un módulo de avisos publicitarios embebido entre las notas, de manera de poder comunicarte el próximo call for papers y/u otras novedades

     

    annotations-emphasizing 
    Figura 1 - Resaltado de texto y comentarios del lector

    Es una alternativa a leerlo directamente de la web, ya que los navegadores requieren de un acceso al servidor cada vez que quieras leer un artículo, y si por alguna razón no hay conexión disponible te van a tirar un error (no: el caché del browser con suerte va a funcar si le diste al back button para volver a una página cacheada en esa sesión)

    En este caso, en cambio, el proceso de descarga es una sincronización de datos que queda almacenada localmente (disparada ya sea bajo demanda o al abrir la aplicación). A partir de allí toda la navegación es local con lo cual no hay más ancho de banda involucrado hasta la próxima sincronización. Cada sincronización descarga sólo las novedades (esto es, artículos inexistentes localmente, o bien existentes pero con una versión local anterior). Si la sincronización no fuese posible por algún motivo (no hay conexión, etc), los datos preexistentes localmente siguen estando disponibles

    Pero la capacidad de operación fuera de línea (offline) no es la única ventaja ofrecida por este Reader: su idea es adaptar la lectura a las capacidades de despliegue en pantalla, entonces el texto y los gráficos se acomodan automáticamente al espacio disponible (te pasó en un browser de tener que escrolear para encontrar la imagen a que se hacía referencia, o agrandar el tamaño de la letra y que se desacomode todo?)

    Por ejemplo, fijate que la figura 1 que pegue más arriba. Quedó ahí: más arriba. Y aparece allí porque el tag HTML <IMG SRC="..."/> que puse, lo puse allí. Ahí queda pues. En cambio en esta aplicación, el texto se organiza según páginas de visualización en base al estado actual (tamaño del área de despliegue, etc). Si el vínculo a la imagen aparece en esa página de visualización, tenés garantizado que la imagen en algún lugar de la ventana se va a acomodar para que la puedas ver completa

    También, el texto se organiza automaticamente en columnas según el tamaño de letra elegido (más columnas si la letra es más chica, para que no te caigas del renglón smile_nerd). En ese sentido, las imágenes se escalan acorde a la cantidad de columnas disponibles

    El Reader te habilita a resaltar párrafos a los que luego quieras volver a ubicar, así como también agregar tus propios comentarios al texto. A ese respecto, te podés armar una lista de lectura (reading list) con artículos que quieras ubicar rápido (sin tener que acordarte en qué número habían salido publicados), similar a los bookmarks del browser pero, nuevamente, sin la necesidad tener que acceder al servidor cada vez

     

    reading_list
    Figura 2 - Lista de lectura consolidando artículos en varios idiomas

     

    Siendo que el Journal se viene publicando desde el 2004, a esta altura va juntando un buen volumen de data como para poder ubicarla inmediatamente. En general cada número tiene un tópico principal (SOA, Software as a Service, etc) pero siempre uno o dos artículos extra a ese tópico son también publicados. Por esto mismo, la aplicación incluye un buscador que clasifica sus resultados por orden de relevancia

     

    searching
    Figura 3 - Resultados de búsqueda de artículos relacionados con "modelo de datos", clasificados
    según relevancia de ese tópico en el artículo en general

     

    Con esta aplicación queríamos ejemplificar un par de cosas:

    • Software + Services. No es un mero cliché sino algo en lo que creémos de verdad. Yo mismo admito haber sido alguien que en su hora defendió a muerte el concepto de "ir a la web", "llevar todo a la web", y me cerraba el concepto de la "network computer" (una computadora de muy bajo costo que basicamente iba a ser capaz de conectarse a Internet y consumir la mayor parte de su software directamente de allí). Nunca pasó nada con la famosa "network computer" que alguna vez Larry Elison (CEO de Oracle) dijo que iba a marcar el fin de la PC y (no lo dijo pero todos esperaban que dijera) presuntamente del principal vendedor de software para PCs. Es hoy incluso difícil encontrar referencias a "network computer". Las más actuales que encontré son viejísimas: Microsoft (2001), Search400 (1999)
      Nunca pasó nada porque las PCs tradicionales con los años se fueron abaratando con lo cual la principal premisa de "ir a menos para ser más" perdió gravidez. Irónicamente esas compus baratas iban a costar entre 500 y 1000 dólares. Hoy eso es lo que cuesta una notebook con Windows Vista (sistema operativo éste que no cabe precisamente en un diskette)
      Software plus Services propone hostear atrás de la nube aquellos servicios que se actualizan dinámicamente, habilitando localmente una capa de software para aquellas funciones relacionadas con actividades del usuario junto a todo aquello que se quiera disponer en forma autónoma (aprovechando, de paso, recursos de hardware locales). Originalmente este concepto surgió como "smart client" (cliente inteligente), en contraposición al "thin client" (cliente delgado) que promovía "llevar todo a la web". Esa misma idea hoy se rebautizó como Software más Servicios (S+S) como una propuesta ampliada al Software as a Service (Software como un Servicio o SaaS). No como una alternativa a SaaS sino tomando a éste como un caso particular donde nada se hostea localmente
      En ese contexto podemos decir que la web del Journal actúa como SaaS en tanto que el Reader juega el rol de S+S, capisce?
    • User Experience (UX). Esto, aunque no parezca, es un derivado de aplicar S+S o, en otras palabras, una motivación para aplicar el concepto del punto anterior tiene que ver con la experiencia que le queremos brindar a los usuarios. Te voy a contar una anécdota de este proyecto: un amigo a quien le mencioné en lo que andaba abocado hace un tiempo atrás me respondió que era innecesario ya que con los avances en materia de comunicaciones, en un tiempo más iba a haber internet hasta en el desierto de Atacama y con eso hablar de offline sería innecesario. A ver: yo no tengo ninguna duda de que Internet ya sale hasta por los cajones de la mesa de luz (los que me tienen en su lista del messenger sabrán de las veces que me han encontrado chateando en el bus, porque no sé por allí pero acá hay Internet en los autobuses)
      Sin embargo, así como lo hay... deja de haberlo. Si por hache o por be el servicio no está disponible, pues agua y ajo. Me acuerdo meses atrás de un hotel que paré en Los Ángeles. Tenían internet gratis en las habitaciones, pero no funcionaba. Le hice saber al conserje y me dio las gracias (además de disculparse por las "inconveniences"). Y ahí quedó, no?
      Pero además, el concepto del browser como cliente universal me parece hasta cierto punto cuestionable. Sirvan las características del Reader contadas acá como ejemplo de cosas que el browser no provée per sé, excepto picar una batahola de código entre server-side y JavaScript (además de lidiar con manejo de sesión, escalabilidad, latencia de red, etc). Complicado de desarrollar, y una experiencia de usuario que en el mejor de los casos se va a arrimar. Son loables los progresos alcanzados con tecnologías RIA (por Rich Internet Applications) como AJAX o Silverlight; yo mismo escribí una serie sobre la web social (Web 2.0) enumerando patrones y tendencias actuales. Pero a cada cual según su necesidad: queremos algo disponible en cualquier plataforma en forma inmediata, sin necesidad de instalar nada? Tecnologías basadas en la web son sin duda la solución (y para ello lo más probable es que resignemos parte de la experiencia de usuario, y nadie se va a suicidar por ello si no había requerimientos de experiencia de usuario especificados de antemano). Queremos, en cambio, privilegiar la usabilidad, tomar ventaja de recursos locales (almacenamiento, otras aplicaciones disponibles, etc), reducir tiempos de espera (especialmente para descargar información que ya alguna vez habíamos descargado y no se había renovado)? Bueno, si la respuesta es afirmativa, ahí es donde la primera S de S+S (Software más Servicios) adquiere relevancia. Ahí está el Reader, pues
      Para cerrarte la anécdota que te contaba de mi amigo, es cosa de no creer pero justamente una vuelta me pasó con él que quiso dejar un comentario en un artículo de mi blog (para colmo justo un artículo de SaaS!!!). Se escribió todo un speech (interesante por cierto, creo incluso más jugoso que mi propio artículo), pulsó "Aceptar" para mandar todo el choclo y... "The site could be temporarily unavailable or too busy. Try again in a few moments." Todavía mi amigo se había enojado conmigo por eso, por tener mi blog en ese servidor, etc smile_regular Si me llega a pasar eso en el desierto de Atacama, la primera vicuña que se cruce es tapado

    La experiencia también nos sirvió (o me sirvió) para afilar mis cualidades de administrador de proyectos: no teníamos ni todo el tiempo del mundo ni tampoco un equipo de gente atrás apoyando. Teníamos, sí, el core que se había usado meses atrás con el New York Times y otros diarios que podríamos decir que incluía gran parte de la lógica. No obstante, no preveía soporte multilenguaje y por ende la persistencia de este estado (es decir, si cuando lo cerraste lo tenías en español, asumamos que es que lo querés volver a encontrar en la lengua de Cervantes la próxima vez que lo uses). Bueno, en ese tipo de cosas estuvimos trabajando este último tiempo

    Cómo de experiencia de usuario se trataba, hubo que tener en cuenta que hoy por hoy los usuarios mayoritariamente tienen Windows XP SP2, que no incluye .NET 3.0 (requerido ya que la aplicación está basada en Windows Presentation Foundation). Por tal motivo llevamos el análisis hasta ese ámbito: el instalador tenía que hacerse cargo de todo (controlar la presencia de los requisitos, instalarlos en caso de que no estén presentes, etc). Analicé MS Installer versus ClickOnce, qué pasa si necesitás que quien lo instala acepte un EULA (end-user license agreement o acuerdo de licencia de usuario final) y una larga lista de etcéteras. Bueno, no lo voy a contar todo ahora pero se viene un artículo al respecto de distribución de aplicaciones (escenarios -usuarios desconocidos vs usuarios de tu organización-; tecnologías -MS Installer, ClickOnce, scripting-; y demás)

    Para cerrar, y como incidencias reconocidas, nos han reportado ya algunos incidentes:

    • El Reader no detecta bien proxies (o no hereda, por caso, la configuración del Internet Explorer)
    • Si en una página de visualización hay más de una imagen que desplegar, de momento despliega sólo una. Es un issue del core y según me contaron los que trabajaron en él, lo tendrían ya resuelto (por lo que voy a incluirlo en la versión 1.0 a liberar en el primer trimestre del 2008)
    • La facilidad de poner comentarios o realzar textos no se puede, hoy, aplicar a imágenes
    • El envío de artículos vía mail, ni siquiera lo mencioné más arriba como característica porque no estoy conforme con lo que pude hacer
    • Lo mismo para la opción "guardar" artículos

    Bueno, y debe haber otras más que yo todavía no detecté (pero vos podés hacerlo fingerscrossed)

    El Reader versión beta está ahí disponible desde fines de Noviembre. Dos días después de su lanzamiento ya se podía leer una crítica en InfoQ: http://www.infoq.com/news/2007/11/aj-reader

    Joojojoojooojojojojojooooooojjooo!! Feliz Navidad!!! smile_party