martes, 21 de febrero de 2012

Complejidad Innecesaria? El Infierno de Dante?





Introduccion

A ver, para que se comprenda el siguiente articulo, los que escribimos este blog, fuimos en su tiempo adherentes de correr detrás de la ultima tecnología y que a mayor complejidad, mayor placer por dominar temas complicados, por aplicar conocimientos teóricos, etc. Era además mucho más interesante plantear un sistemas de colas concurrentes usandos colas en memoria con PVM (una máquina virtual paralela que permita ejecución paralela en servidores) que resolverlo con una simple tabla en base de datos. Lo cierto es que estabamos equivocados, y nos fuimos dando cuenta a lo largo de todas las veces que complicamos soluciones de manera totalmente innecesaria y luego se nos volvió contra nosotros mismos.

Indice de Complejidad de Arquitectura

Cada tanto me gusta inventar "números Kafkianos", esto es inventar medidas de algo que no estén basados en la teoria de los grandes números, en álgebra ni en nada muy "serio" pero que provengan del sentido común y/o cierto conocimiento y que sean aplicables a temas de la vida diaria. El porque le achaco al pobre Kafka la paternidad de este tipo de números sin el menor fundamento es materia de opinión psicológica, en la que no vamos a entrar.

 Vamos a definir entonces el índice de Complejidad de la Arquitectura de una aplicación, ICA (app) como el número de componentes lógicos o de provisión de datos que necesita la aplicación para funcionar. Esto es sin contarse a ella misma, es decir al código de la aplicacion que provee la lógica princpial en si, ya que es obvio que se necesita. Asi, tenemos que una vieja aplicación Desktop (las que corrían o corren en los clientes mismos, las de antes), como, para citar un ejemplo que todavia sobrevive, una planillita excel(que no acceda a base de datos), un Paint, un Visio (versión desktop), Autocad, etc., tienen :

ICA( app desktop) = 0 (en general).

Okey, Si, es verdad que no estamos teniendo en cuenta componentes de la infraestructura de red, routers, proxys, firewalls, ni virtualización de servidores, ni siquiera componentes de los sistemas operativos. Tampoco tomamos en cuenta librerias de subcomponentes de una aplicación web como por ejemplo log4j (si tenemos log4j dependemos en cierto sentido de como este configurado, en su impacto sobre la aplicación, etc.). Pero permitanme dejarlos de lado, vamos a algo mucho más simple. Una aplicacion Cliente-servidor, que accede a una base de datos (estilo las apps basadas en Oracle forms, Java Desktop aplication, app tipicas Visual Basic version x , etc) tiene :

ICA (app client-server) ) = 1 (en general)

Además de si misma necesita una base de datos configurada "up and running", y depende de ella para proveer servicios al usuario.

Un simple y querida aplicacion web, sea en Java, .NET, PHP o Ruby on Rails, tiene:

ICA (app web) = 3 (en general)

Es decir, debe funcionar un browser o navegador en el cliente (con su correspondiente configuracion, nada trivial, de cookies, activex, etc.), una base de datos (un servidor de base de datos, más el espacio de tablas o esquemas necesarios, seguridad, etc.) y un servidor de aplicacion, de nuevo, que este funcionando y correctamente configurado. Y si, ya se que la complejidad de hacer aplicaciones varía si el lenguaje es Java, .NET o Rails.Y ni siquieta estamos considerando que la aplicacion use ajax o no. Lo se. Continuen conmigo un poco más.

Mundo HTML5 ( Appweb con Javascript en el navegador, ajax, JQuery (que simplifica enormemente el desarrollo Javascript!)), todo esto da :

ICA (app web) = 4 (IC(app) web + 1 de funcionamiento de la lógica JS en el cliente)

Llegando al mundo SOAP, la cosa se pone interesante, a ver, cuenten conmigo, para que una applicacion que accede a servicios a través de SOAP funcione tienen que funcionar a la vez y estar correctamente configurados: 1 browser (repito, la configuracion no es trivial) 1 Aplication Server ( de la app. en si) 1 Base de datos (por lo menos) 1 Enterprise Service BUS 1 Aplication Server (adonde reside el servicio) 1 registro de servicios (Service Registry)

ICA(app SOAP) = 6 !!!

y eso que estamos contando que accede a servicios residentes en un mismo aplication server, si accediera a n servicios en distintos servidores, la formula deberia ser algo asi como:

ICA(app SOAP) = 5 + n * 1, con n>=1.

Estoy viendo que bien podriamos llamarlo Indice de acoplamiento de la infraestructura de un sistema.

Al Mundo SOAP le sumo (+) BPM :

ICA (app SOAP + BPM) = 7 + n * 1 ( al ICA(SOAP) le sumamos el BPM y su base de datos)

A ver, es claro que cada aumento en la complejidad que hemos dado hasta aqui está de alguna manera justificado porque se supone que provee un beneficio, a veces más o menos tangible, para el usuario final. Una primera pregunta es: Esto, se percibe realmente así? Esto, Es realmente así? A ver, es claro que hay algunas situaciones adonde amerita aumentar la complejidad, depende siempre del contexto. No estamos diciendo que nuuunca se deban utilizar una cache distribuida, por ejemplo.

Lo que es seguro es que ese supuesto beneficio no viene sin un costo. Para que funcione una de estas aplicaciones, más alla de la complejidad inherente de su propia lógica deben funcionar correctamente TODOS y cada uno de los otros elementos a los que está acoplada, y no solo deben estar levantados y corriendo. Deben hacerlo sin errores, con buen rendimiento, deben estar correctamente configurados y sincronizados , muchas veces referenciándose entre sí de manera exacta, en un millar de archivos xml distintos, todo esto, para que el conjunto funcione.

A la vez, un error, en configuración o lógica, o un problema de escalabilidad por pequeño que sea, en cualquier eslabón de esta larga cadena hace que el todo no pueda funcionar. Se producen errores , o problemas de performance , a menudo de maneras impredecibles e indeterminadas. Esto ES asi porque la combinatoria de posibles problemas explota de manera exponencial. Y ni que hablar de tratar de encontrar problemas de concurrencia o simplemente debuggear errores.  No es de extrañar que las aplicaciones sean cada vez menos confiables.

Las aplicaciones actuales que vemos, corrijanme si me equivoco, no es raro que posean 2 o 3 datasources que acceden a diferentes fuentes de datos, servicios varios de diferentes aplicaciones, conectores con algun ERP o sistemas externos, interfaces con algún Mainframe, Caches distribuidos, y etc y etc. Traducido a dos palabras: Una Pesadilla. y no solo para la pobre gente que debe administrarlo y mantenerlo, piensen tambien en el costo extra ($$) que genera esa administración y mantenimiento.
Y no estamos hablando todavia (ahora si!) del costo y la dificultad que implica armar ambientes de tests y desarrollo que permitan soportar esta infraestructura para desarrollar nuevas aplicaciones (mocks, instancias de desarrollo, de testing, para cada uno de los componentes interdependientes, servicios, servidores varios, etc.). Todo lo cual dificulta aún más el testing de las aplicaciones, ya de por si una de las tareas más dificiles del desarrollo.

Dejamos para un siguiente articulo el siguiente "dilema", viene Cloud Computing (la computación en las Nubes) a incrementar o  disminuir la complejidad de la arquitectura de las aplicaciones? 

Ok, no soy naive y entiendo que los grandes Vendors tienen que inventar "modas" y seguir vendiendo "Enterprise Integration Aplication" servers, Parallel computing infrastructures, Aplication servers con servicios cada vez más complejos o la última moda en portales de agregacion de contenidos. También comprendo que en el afán por llegar al futuro, con ánimo de mejorar y brindar nuevos productos hay mucha gente honrada que plantea estas infraestructuras de buena fe, y con las mejores intenciones pero........

No nos estarán haciendo recorrer los 9 círculos del infierno?