30 Mar 2012

Aplicaciones escalables,distribuidas y rapidas con ZeroMQ

Zeromq

En la actualidad una aplicación no es un modulo aislado que sirve de punto de entrada o salida de datos, este se interconecta con otras aplicaciones, ya sea para recibir o enviar información, como parte de un flujo de información dentro de empresas o negocios. Existen muchas formas de interconectar aplicaciones, por lo general usando protocolos como HTTP, UDP, TCP, Websockets, etcétera; en ocasiones no solo se requiere comunicar entre distintas aplicaciones, si no modulos que se encuentran en distintos procesos hospedados en un servidor o una comunicación interproceso en la aplicación.

ZeroMQ nace en 2007 como una  respuesta a estas necesidades. Su creadores lo definen como sockets con esteroides o mailboxes con enrutamiento y sistema de mensajería que tiene un rendimiento usando hardware limitado, funcionando de manera asíncrona y en multihilos, con latencia muy baja y  escalable, además que no solo soportar el patrón de intercambio de mensajes de publicador-suscriptor, si no poder implementar otros mecanismos de comunicación entre los nodos involucrados.

ZeroMQ en resumen es una librería de comunicación que puede agregarse a tu aplicación y actuar también como una herramienta de concurrencia. Proporciona un mecanismo de sockets para el intercambio de mensajes entre procesos, interproceso, TCP o multicast. Es posible conectar estos sockets en patrones N-to-N como pueden ser fanout, publisher-subscriber, task distribution, request-reply o algun patrón personalizado. Es increíblemente rápido,por lo cual puede ser base para una solución cluster, es asíncrono y escalable.

Porque es popular o por que usar zeromq:

  • Es código abierto y libre, esta soportado por una comunidad activa y grande, mas de 50 voluntarios contribuyen al código fuente, fuera de la compañía Imatix.
  • Fue desarrollado con una API ultrasimple y basada en sockets BSD, la API es familiar, fácil de aprender e idéntica en todos los lenguajes de programación.
  • Implementa patrones de mensajería como pub-sub, distribución de cargas de trabajo y request-response, por lo cual es sencillo resolver de conexión entre aplicaciones
  • Funciona con una gran cantidad de lenguajes de programación (C, C++, Java, Ruby, Python, Javascript, C#, Haskell, Erlang, PHP, etc) y funciona en todas los sistemas operativos (Linux, Windows, Solaris, OSX,etc) por lo cual conectar aplicaciones o piezas de aplicaciones es posible.
  • Proporciona un modelo consistente para las API en todos los lenguajes, ZeroMQ se puede aprender con un lenguaje y aplicarlo en otro sin problemas.
  • Es LGPL por lo cual puede usarse en soluciones de código cerrado, aplicaciones gratuitas u open source. 
  • Es una librería embedida, por lo cual no existen agentes que iniciar o administrar, menos piezas que controlar y menos probabilidades que algo falle.
  • El uso de CPU es muy bajo así como el de la memoria.

 

¿Que necesitamos para comenzar?

Un lenguaje de programación que dominemos o nos guste

  • Las librerías de Zeromq que pueden descargar de esta url: http://www.zeromq.org/area:download  (es preferible utilizar la versión estable, ya que los binding por lo general funcionan con esa versión y no con las últimas versiones beta)
  • Compilar las librerías en el sistema operativo de su preferencia
  • Instalar el binding para su lenguaje de programación, la lista de bindings y como instalarlos pueden consultarla en esta url: http://www.zeromq.org/bindings:_start

En el caso de los siguientes ejemplos, vamos a utilizar ruby en un entorno Linux, por su facilidad de instalación y para efectos de explicar cada uno de los puntos. Para lo cual se requiere tener instalado lo siguiente:

  • Ruby 1.9.1 instalado en el equipo,se puede instalar con sistema de administración de paquetes de la distribución o se puede descargar de:
  • La librería de ZeroMQ compilada e instalada en tu entorno Linux, se puede descargar el código fuente de:
  • La gema ZMQ que se puede instalar usando el comando: gem install zmq

Show me the code!!!

Vamos a comenzar a usar ZeroMQ implementando un patrón Request-Response, es decir envió petición a una aplicación y esta debe responder. Este patrón de comunicación se ilustra de la siguiente manera:

Image009
Donde yo solicito a una aplicación la hora actual, la aplicación que envía la petición la podemos definir con el siguiente código:

 

require "zmq" 

context =ZMQ::Context.new(1) 

p "app de request" 

envio=context.socket(ZMQ::REQ) 

envio.connect("tcp://127.0.0.1:9000") 

for i in 1..10 do 

       envio.send(i.to_s() +".-Que horas son?") 

       respuesta = envio.recv 

       p respuesta

       p "enviado"

end

p "Termino el envio de mensajes"

 

En el ejemplo 1 se ve como invocamos la librería de ZeroMQ. Después se crea un objeto de contexto con el cual podemos crear nuestro socket. En este caso vamos a utilizar un socket de request(ZMQ::REQ) y nos conectamos(usando el método connect) a un puerto libre en un equipo por medio de tcp, en este caso al equipo donde estará el servidor que nos va a responder (tcp:// 127.0.0.1:9000).

A continuación se crea un ciclo donde realizamos una serie de envíos de las peticiones  usando el método send. El método send nos permite enviar información ya sea una cadena de texto o un arreglo de bytes y es inmediatamente enviado al servidor que va a responder nuestras peticiones.

Como estamos usando un patrón Request-Response, cada petición espera una respuesta, por lo cual inmediatamente que se envía una petición se espera una respuesta usando el método recv, el método recv recibe la información que envía el cliente y la devuelve ya sea como una cadena de texto o arreglo de bytes.

 

Para poder responder a las peticiones, necesitamos un servidor por lo cual utilizaremos el siguiente código:

 

require "zmq" 

context =ZMQ::Context.new(1) 

p "app de response" 

respuestas= context.socket(ZMQ::REP) 

respuestas.bind("tcp://127.0.0.1:9000") 

loop do 

       request = respuestas.recv 

       p request 

       respuestas.send(Time.now.to_s()) 

       p "Respuesta enviada" 

end

 

En el ejemplo 2 observamos cómo se crea el contexto de ZeroMQ y posteriormente se crea el socket, a diferencia de la aplicación de peticiones, en este caso se usa un socket de respuestas(ZMQ::REP)  y se asocia a una ip y puerto del equipo (tcp:// 127.0.0.1:9000).

Creamos un ciclo donde se van a estar recibiendo las respuestas utilizando el método recv de nuestro socket, y por medio del socket enviamos la respuesta usando el método send, se esa manera implementamos un mecanismo  de comunicación entre aplicaciones.

Iniciando con el siguiente comando el ejemplo 1: 

ruby request.rb

 

Y con el siguiente comando en otra ventana de la línea de comandos el ejemplo 2:

ruby response.rb

El resultado de estos dos comandos es similar a esto:

Salida de Request.rb

Salida de Response.rb

"app de request"

"2012-01-22 02:11:48 +0000"

"enviado"

"2012-01-22 02:11:48 +0000"

"enviado"

"2012-01-22 02:11:48 +0000"

"enviado"

"2012-01-22 02:11:48 +0000"

"enviado"

"2012-01-22 02:11:48 +0000"

"enviado"

"Termino el envio de mensajes"

"app de response"

"1.-Que horas son?"

"Respuesta enviada"

"2.-Que horas son?"

"Respuesta enviada"

"3.-Que horas son?"

"Respuesta enviada"

"4.-Que horas son?"

"Respuesta enviada"

"5.-Que horas son?"

"Respuesta enviada"

Si nosotros hacemos la prueba e iniciamos el ejemplo 2  y  creamos varias instancias del ejemplo 1, veremos que a todas las peticiones se les da respuesta, estoy se conoce como fair-queuing, es decir todas las peticione se les asigna una prioridad igual y se tratan de atender mientras existan recursos suficientes para procesarlas en paralelo.
El punto importante en la comunicación de aplicaciones en ZeroMQ es que existen los siguientes patrones o métodos de comunicación:

Nombre

Compatible con

Dirección

Balanceo

Patrón envio/recepción

REQ

REP

Bidireccional

Round-robin

Envio,recepción,envio,recepción…

REP

REQ

Bidireccional

Fair-queued

Recepcion,envio,recepción,envio

DEALER

ROUTER,REQ,REP

Bidireccional

Round-robin/ Fair-queued

Sin restriccion

ROUTER

DEALER,REQ,REP

Bidireccional

Fair-queued

Especial

PUB

SUB

Unidireccional

Fan out(envio a todos los nodos conectados)

Envio solamente

SUB

PUB

Unidireccional

Fair-queued

Recepcion solamente

PUSH

PULL

Unidireccional

Round-robin

Envio solamente

PULL

PUSH

Unidireccional

Fair-queued

Recepcion solamente

PAIR

PAIR

Bidireccional

No tiene 

Sin restricción pero solamente con un nodo a la vez 

Algunos son compatibles con otros y pueden usarse en combinación para crear patrones de distribución o balanceo de cargas, además de poder invertir el orden del servidor(binding) y de los clientes(connect) con lo cual cambiando solamente algunas partes de los códigos anteriores en cada uno de los scripts:

Request2.rb

 

require "zmq" 

context =ZMQ::Context.new(1) 

p "app de request" 

envio=context.socket(ZMQ::REQ) 

envio.bind("tcp://127.0.0.1:9000") 

for i in 1..100 do 

       envio.send(i.to_s() +".-Que horas son?") 

       sleep(0.2) 

       respuesta = envio.recv 

       if envio.getsockopt(ZMQ::RCVMORE) 

               identClient=envio.recv 

       end 

       p "Enviada por:" + identClient +" Resp:" +respuesta 

       p "enviado"

end

 

p "Termino el envio de mensajes"

 

Response2.rb

 

require "zmq"

context =ZMQ::Context.new(1)

identidad=ARGV[0]

p "app de response:" +identidad

respuestas= context.socket(ZMQ::REP)

respuestas.connect("tcp://127.0.0.1:9000")

loop do

       request = respuestas.recv

       p request  respuestas.send(Time.now.to_s(),ZMQ::SNDMORE)

       respuestas.send(identidad)

 

       p "Respuesta enviada"

end

Al invertir la manera en que nos asociamos a un puerto con nuestro sockets, podemos cambiar la funcionalidad de nuestra aplicación, en este caso vamos a crear una aplicación que hace peticiones a una serie de aplicaciones que van a recibir las tareas de manera balanceada, es decir se van a repartir una por una cada una de las peticiones de manera ordenada y equitativa.

Otro elemento que agregamos es la identidad. En este caso la aplicación que envía las peticiones, espera una repuesta que se compone de varias partes, ZeroMQ nos permite dividir un mensaje en partes, para saber si todavía quedan partes por procesar durante la recepción de un mensaje, utilizamos el método getsockopt y le mandamos de parámetro la propiedad ZMQ::RCVMORE, de esa manera si existen más partes del mensaje, devuelve un valor verdadero, y debemos seguir recibiendo datos con el método recv, en caso contrario significa que ya no hay mas partes que forman parte de ese mensaje y debemos esperar a que llegue un nuevo mensaje.

Del lado de la aplicación de respuestas, queremos enviar la identidad de nuestra aplicación y la respuesta a la petición que nos hicieron, por lo cual dividimos el mensaje en dos, enviamos primero una respuesta con el método send, pero agregamos un parámetro ZMQ::SNDMORE para que ZeroMQ le indique al receptor que está enviando una serie de partes que integran un mensaje. Cuando queremos terminar la serie de partes del mensaje, solo usamos el método send sin ningún parámetro, esto cierra la serie de partes de un mensaje.

Si iniciamos con el siguiente comando el ejemplo 3:

ruby request2.rb

Y después iniciamos el ejemplo 4 varias veces en distintas ventanas de la línea de comandos, cambiando el parámetro que enviamos, que es el nombre del nodo:

ruby response2.rb nodo1

ruby response2.rb nodo2

ruby response2.rb nodo3

Lo anterior nos muestra un escenario de balanceo de cargas, donde una aplicación reparte mensajes por medio de round-robin a los nodos que se conectan a ella, en una distribución como la siguiente:

Image008

 

Donde cada uno de los mensajes es repartido a cada uno de los nodos que están conectados, una característica interesante de este balanceo de cargas, es que pueden agregarse más nodos simplemente con conectarse al socket, no se requiere realizar algún otro tipo de proceso adicional en el servidor, por lo cual es relativamente fácil escalar un servicio o repartir tareas entre uno o mas nodos.

Derivado del caso anterior, observamos que nos da una salida en la línea de comandos similar a la siguiente:

Salida de Request2.rb

Salida de Response2.rb nodo1

Salida de Response2.rb nodo2

Salida de Response2.rb nodo3

"app de request"

"Enviada por:test01 Resp:2012-01-22 18:25:26 +0000"

"enviado"

"Enviada por:test02 Resp:2012-01-22 18:25:26 +0000"

"enviado"

"Enviada por:test03 Resp:2012-01-22 18:25:26 +0000"

"enviado"

"Enviada por:test01 Resp:2012-01-22 18:25:26 +0000"

"enviado"

"Enviada por:test02 Resp:2012-01-22 18:25:27 +0000"

"enviado"

"Enviada por:test03 Resp:2012-01-22 18:25:27 +0000"

"enviado"

"Enviada por:test01 Resp:2012-01-22 18:25:27 +0000"

"enviado"

"Enviada por:test02 Resp:2012-01-22 18:25:27 +0000"

"enviado"

"Enviada por:test03 Resp:2012-01-22 18:25:27 +0000"

"enviado"

"Termino el envio de mensajes"

"app de response"

"1.-Que horas son?"

"Respuesta enviada"

"4.-Que horas son?"

"Respuesta enviada"

"7.-Que horas son?"

"Respuesta enviada"

"app de response"

"2.-Que horas son?"

"Respuesta enviada"

"5.-Que horas son?"

"Respuesta enviada"

"8.-Que horas son?"

"Respuesta enviada"

"app de response"

"3.-Que horas son?"

"Respuesta enviada"

"6.-Que horas son?"

"Respuesta enviada"

"9.-Que horas son?"

"Respuesta enviada"

¿Dónde puedo aplicar ZeroMQ?
Todo suena muy interesante, pero realmente existen razones para utilizarlo en alguno de mis proyectos, a continuación hay algunos ejemplos en los cuales se podría aplicar ZeroMQ:
  • Asignación de tareas de procesamiento complejas a varios nodos en distintos equipo y realizar procesamiento en paralelo.
  • Comunicación entre procesos, el intercambio de mensajes es muy rápido y más efectivo que otros protocolos, además utilizando JSON o protocol buffers como serialización, se tiene una muy buena solución de crear medios de comunicación entre tecnologías en distintos lenguajes.
  • Sistemas de comunicación de nodos descentralizado basados en directorios, puede crearse un servicio que tenga la lista de los nodos en la red y estos pueden establecer comunicación directa sin pasar por el servicio central.
  • Monitoreo por heartbeat, por tener poca latencia y ser muy rápido, se puede implementar que distintas aplicaciones reporten el estatus activo a una aplicación central utilizando un patrón REQUEST-RESPONSE como el anteriormente explicado y saber cuándo una aplicación esta  fuera de línea (por qué no responde el hearbeat).
  • Mensajes PUSH, es posible enviar mensajes a una serie de nodos escucha y que estos lo filtren por medio de su entidad, es decir solo enviar el mensaje a un nodo receptor de entre varios que estén conectado al servidor.
  • Rutas de mensajes, es posible enviar mensajes y establecer rutas de pasos entre distintos nodos para crear proxies, repartidores o embudos de procesamientos, de esta manera tener una infraestructura de procesamiento robusta para un sistema.

¿Quienes usan ZeroMQ?

Algunas de las compañías que usan actualmente ZeroMQ como parte de la infraestructura de sus aplicaciones son:

  • AT&T
  • Cisco
  • Electronic Arts
  • NASA
  • Weta digital
  • Zynga
  • Twitter Storm, un sistema de procesamiento complejo basado en eventos
  • Microsoft
  • Cern
  • Spotify

Al mismo tiempo de cientos de proyectos de código abierto que pueden encontrar en internet, la comunidad de ZeroMQ ha crecido mucho en los últimos años porque es una herramienta que permite  integrar cómputo distribuido sin agregar complejidad al código de nuestras aplicaciones.

 

Conclusión

La pregunta que uno puede hacerse, es porque usar ZeroMQ de mi esquema de comunicación actual entre mis aplicaciones, las razones por las que podría justificar un cambio de este tipo seria:

  • Rendimiento, procesar miles de mensajes no implica grandes costos de procesamiento o memoria.
  • Velocidad,  En algunas pruebas realizadas de manera aislada es capaz de procesar 32,000 mensajes por segundo en un equipo bastante modesto, por lo cual con una infraestructura adecuada puede procesar en una medida de cientos de miles de mensajes por segundo.
  • Sencillez,  es muy sencillo entender cómo funciona el enlace entre los sockets y en que puerto operan, así como los patrones que existen para las implementaciones.
  • Escalabilidad, una aplicación que se comunica con ZeroMQ puede ser ampliarse en tiempo real, agregando nodos, los mecanismos de balanceo de cargas y atención de la cola de mensajes son manejados por la librería y facilita la implementación.

Implementar ZeroMQ en una aplicación es bastante sencillo, además de ser compatible con una gran cantidad de plataformas de desarrollo, solo es encontrar el uso adecuado a la tecnología y que uno tenga ganas que comenzar a experimentar con cómputo distribuido en la empresa o proyectos personales, además de poder usarse en conjunto con otras tecnologías o como sistema de comunicación vertebral de la empresas y los puntos finales de consumo usen otras tecnologías como HTTP, TCP, Webservices, etc.

Con infraestructura en la nube y una creciente tendencia a ofrecer servicios empresariales que usan técnicas similares a la nube, es indispensable que las aplicaciones se desarrollen con mecanismos de escalabilidad y comunicación que permitan soportar de manera elástica cargas de procesamiento, hoy puede ser que nuestra aplicación atienda diez personas, pero el día de mañana puede ser que estemos atendiendo a miles de personas en distintos puntos del planeta, solo necesitamos el canal adecuado de comunicación  y ZeroMQ viene a resolver ese problema.

Enlaces recomendados:

 

 

 

 

24 Feb 2012

10 vicios del desarrollo en una empresa(que no se dedica a desarrollar)

Muchas veces en nuestro andar en diferentes empresas, ya sea ofreciendo consultoria, estando contratados o por platicas entre compañeros programadores, escuchamos de como el ambiente empresarial del desarrollo de software esta plagado de vicios o cosas que no existen en ambientes como los del startup o freelacing. A lo largo de mi vida laboral me he encontrado con algunos de ellos, quizas esten errados o no muy claros, pero creo que muchos van a identificarse con algunos de ellos.

1.- Si no esta fallando, no lo arregles

Esta premisa es pregonada hasta el cansancio por mucha gente del mundo enterprise, un caso que me sucedio recientemente fue la propuesta de un compañero para migrar de version de base de datos(sql server) a una version mas reciente, por sus multiples caracteristicas y por que se tenian las licencias pagadas. Independientemente que se realizaron una serie de pruebas de escritorio,con distintas aplicaciones si estas funcionaban o no con la nueva version, ademas del papeleo propio del proceso de autorizacion y e instalacion por parte del area encargada de los servidores. La primera pregunta que salto fue: ¿Por que migrar, si funciona bien?, ok pero hay ciertas caracteristicas que me ayudaran a facilitar la administracion y mejorar el desarrollo de una aplicacion que use esa base de datos, despues de una serie de discusiones, la razon por la cual se promovio la migracion fue por que el fabricante dejo de dar soporte a esa version.

El punto es, muchas veces la gente esta renuente al cambio y no desea invertir mas tiempo en mejorar o hacer mas facil el trabajo para otros(los programadores son los clientes principales del servicio de base de datos,ellos hacen las apps que la usan), simplemente por que para muchos sysadmin creen que su trabajo es solamente que el foglight o nagios tenga foquitos en verde, y mas bien es ayudar a mejorar el desempeño de las aplicaciones que operan sobre su infraestructura.

2.-Esperemos a que exista una version estable de mas de 3 años

¿Estable? Precisamente cuando alguna entidad te dice que es estable una nueva version, por lo general lo es, creeme, muchas de estas empresas o grupo de desarrolladores llevan mejores practicas de TDD,BDD o QA que las que lleva una empresa que dedica 2% de sus recursos a desarrollo de software. La razon para moverser a una nueva version, la mas reciente, no es por resolver bugs, si no por tener nuevas caracteristicas que nos ayuden, en la informatica, 6 meses son muchos años-internet, por lo cual a veces no podemos darnos el lujo que quedarnos obsoletos por decidia. Adicional a esto, muchas tecnologia tienen excelentes metodos de migracion o se realizan sin problemas las actualizaciones.

3.-¿Open source?Mejor consigue una alternativa donde tengamos que pagar

Open source no es igual a gratis, muchos tienen la idea equivocada que los proyectos open source nacen como el que tres changos que ponen a crear una aplicacion, muchos proyectos open source nacen como la necesidad de una empresa de resolver un problema particular y es liberado para beneficio de muchas personas. Adicional a esto hay muchos proyectos open source que ofrecen servicios de consultoria, soporte y desarrollo ad-hoc para las empresas que quieren pagar por ellos, por eso si una empresa quiere gastar su dinero, ofrezcan esas opciones, ademas al usar open source se tiene una ventaja sobre una solucion de codigo cerrado, si hay un problema, perfectamente puedo solucionarlo yo sin tener que esperar a nadie a que lo resuelva, y envio el parche a quienes desarollan el proyecto, por lo tanto es una relacion ganar-ganar.

4.-Eso funciona para un startup pero para la empresa no

Equivocado, muchos startups son increiblemente mas grandes que toda la infraestructura de TI de la empresa, los startups todos lo dias se enfrentan a problemas de escalabilidad, rendimiento, perfomance, etc. Al aprender como esas empresas tecnologicas crean su infraestructura, nos permite mejorar la capacidad de nuestra infraestructura sin tener que tomar los riesgos que alguna vez experimentaron, ademas que aunque nunca nos vamos a enfrentar a entornos donde tengamos 3 millones de peticiones por segundo, es bueno saber que la infraestructura de nuestra empresa soporta facilmente 500 mil peticiones por segundo, aunque no lo necesitemos.

5.-Procesos, procesos, procesos

Los empresas que ofrecen desarrollo o grupos de desarrollo dentro de una empresa forman parte de una maquinaria mas grande, la cual exige muchas veces que se cumpla un proceso burocratico o de checkpoints para asegurar que todo funcione correctamente, aunque es entendible el esfuerzo, realmente comienza a provocar un problema: Se vuelve mas importante cumplir los pasos que ofrecer un resutlado.

Es decir, tiene mayor prioridad el crear un documento, llenar un formato o solicitud, que ofrecer un producto o solucion de acuerdo a lo que el cliente solicito, es decir nos enfocamos en cumplir con el checklist y dejamos a un lado lo que realmente importa, el producto.

En los grupos de desarrollo dentro una empresa que no se dedica a TI, es mas marcado esta tendencia, de burocratizar y crear esquemas para que los programadores "no se salgan del huacal", pero la verdad es que son estas empresas quienes mas deben adoptar esquemas agiles para el desarrollo, por que su objetivo es cumplir con resultados rapidos y efectivos, no con entregar tres carpetas de documentos. Los documentos y procesos muchas veces no resuelven problemas, si no las aplicaciones.

 

6.-Tengo un martillo y todo lo veo como un clavo

En ocasiones la empresa o alguien compra una herramienta de software, cuando quizas no era necesaria, al comprarla recae la necesidad de buscar donde utilizarla para justificar su compra (logico si no la cabeza de alguien va a volar), el problema es cuando esta herramienta se convierte en el silver bullet, o mas bien metela en un proyecto con calzador.

Me ha tocado proyectos donde resolver un problema es relativamente simple, es algo de talacha y hechar a andar una aplicacion, pero al meter una herramienta o tecnologia a la fuerza, comienza a crearse una sobreingenieria que no viene al caso, esto a ultimas provoca una inversion de tiempo y dinero al intentar integrar a la fuerza una tecnologia no adecuada.

No existe el silver bullet, por lo cual siempre hay que analizar la herramienta adecuada para el problema actual, mucha gente del enterprise primero compra el software o herramienta y despues analiza el problema, siendo que debe ser al reves. De eso podemos aprender mucho de los startups, donde primero analizan el problema y despues ven con que tecnologia lo resuelven, si es que existe, y si no, la crean.

 

7.- Matemos una hormiga a cañonazos

Seria ineficiente, costos y estupido,¿no?, el problema es que cuando tienes una herramienta que cuesta miles de dolares, requieres justificar su uso, que mejor que utilzarla en todos mis proyectos. Y ahi es donde recae el problema de, realmente necesito utilizarlo, o alguna herramienta mas pequeña(y quizas open source y gratutita) me permite hacerlo.

A veces para decidir si usar una tecnologia o no, hagan este calculo simple, vean las caracteristicas de la herramienta, si el 80% de las caracteristicas las vas a usar en tu aplicacion, ok usala, estas usando la herramienta adecuada, pero si solo un 10% de las caracteristicas estan siendo utilizadas, tienes un cañon en la mano.

8.-9 mujeres embarazadas con un 1 mes de gestacion hacen un niño

Mal. no por meter mas gente en un proyecto de 3 meses se termina en 1 mes, a veces hay que ser claros de como funciona el proceso de desarrollo, si realmente necesitas resultados inmediatos, usa metodologias agiles, usa scrum, divide tu proyecto en sprints realistas y da prioridad a tus features que requiere el cliente, muchas empresas deciden meter CMMI o alguna metodologia monolitica por que creen que eso automagicamente va a resolver los problemas, pero no es cierto, tu problema no esta en la metodologia, tu problema esta en que quieres resolver rapidamente problemas pero tu proceso estorba para eso.

9.- Todo mundo quiere se capitan, pero nadie quiere ser marinero

En el entorno enterprise se da un fenomeno, todos quieren mandar,y aunque es loable el querer aspirar a puestos altos, comienza a crearse un deficit de la mano de obra o de quienes realmente solucionan el problema a nivel de bytes, cuando una persona se pasa del lado admistrativo y delega responsabilidades tecnicas a otras personas, esta todo ok, pero si a eso agregamos responsabilidades contractuales ( verificar el cumplimiento de procesos, respetar politicas y lineamientos), responsabilidades administrativas(ir a juntas, asistir a reuniones con el cliente, entregar documentos, timesheets, etc) y a parte responsabilidades operativas (dar soporte, proporcionar asesoria, analizar herramientas, adquisicion de equipo y ser filtro), las tareas rebasan tu capacidad de trabajo y sales poniendo de tu tiempo. Por eso es importante nivelar eso, que necesitas realmente, tener a alguien que supervise que se cumplan las cosas o que se cumplan las cosas. 

El verificar que se cumplan las cosas, es decir, tener un chicote, puede sustituirse con sistemas como pivotal tracker, Team foundation, CodeCamp, etc, darle seguimiento a las tareas de quienes desarrollan puede ser relativamente sencillo y es bueno tenerlo,por que realmente ahi es donde se dan cuenta de la verdadera carga de trabajo. Los superiores que estan sobre el grupo de desarrollo deben enfocarse en convertirse en facilitadores, es decir, si necesito un servidor de pruebas, el deberia proporcionarlo, si requiero una licencia o hardware, el deberia gestionarlo, no el desarrollador.

10.- ¿Nueva tecnologia? No necesito aprenderla,ya se Visual basic 6

El poner de pretexto para aprender nuevas tecnologias, cosas como:

  • Ellos estan obligados a darme el curso
  • ¿Para que? si no vamos a utilizarlo
  • Ahh es que me da flojera
  • Si asi funciona ok
  • Es que venimos haciendolo asi desde hace 10 años
  • No tengo tiempo,no voy a invertir de mi tiempo

Son pretexto sin fundamento, la informatica y especialmente la programacion, son de los pocos trabajos donde se paga por aprender, es decir, para crear una aplicacion de contabilidad, hasta cierto punto tienes que aprender como funciona basicamente la contabilidad, y asi con otros procesos de la empresa donde se requiere automatizar, es decir nos pagan por aprender lo que se  hace manualmente, ponerlo en codigo y que funcione automaticamente, simple, ¿no?.

Entonces si me pagan por aprender, por que no tambien aprender algo mas cercano a lo que me dedico, es decir, un nuevo lenguaje de programacion, una tecnologia, etc. Hay recursos actualmente, sitios con tutoriales, screencast, documentos, codigo fuente, no existe un pretexto real para no aprender una tecnologia, nada mas decision y tiempo, nada es mas triste en la industria que ver como alguien por decidia propia se queda obsoleto en conocimientos, mas cuando se compara con otras personas.

11.- Punto extra: como experto tecnico no voy a subir mas

Las empresas tienden a tener un tope en la jerarquia organizacional para la gente que se dedica al apartado tecnico, si en algun momento alguien aspira a subir en la escala, tendra que dar el gran salto al bando administrativo, lo cual es respetable.

Pero esto siempre deriva en algunos detalles:

  • Un experto tecnico no siempre es buen facilitador, por lo general existen ciertas caracteristicas en la gente que es buen tecnico, como ser hermatico o poco elocuente, carecer de habilidades sociales o de cierto tacto al hablar, que son importantes en un ambiente donde las relaciones y los acuerdos son los que llevan a buen puerto un proyecto
  • Tiene una vision tecnica y no gerencial, ve todo al nivel de infraestructura, que tecnologia se va a usar, como va funcionar la aplicacion, que lenguaje se va a usar, pero no puede ver el enfoque gerencial, es decir, como va a interacturar con otras aplicaciones, como impacta el proceso de la empresa, que riesgos existen con un cliente problematico

Hay gente tecnica que tambien tiene estas habilidades, y se convierten en un excelente administrador, pero hay gente que carece de ellas y da el salto por necesidad, y eso es un problema del enterprise, aspirar a un mejor salario(que muchas veces es la razon de escalar en la jerarquia) o tener delegado cierta capacidad de toma de decisiones puede darse conservandolo en un puesto donde es mas util,es experto y hacer la vida mas facil a los mandos superiores y reditua en mayores beneficios a la empresa que moviendolo detras de una pila de papeles.

 

24 Feb 2012

Petprojects, ¿por qué son importantes?

Muchos programadores tienen proyectos de prueba o alternativos a los que realizan en su trabajo o proyecto principal, principalmente aquellos que trabajan dentro de un esquema tradicional de horarios y oficinas.

Pero qué importancia tienen estos proyectos mascota o alternativos para uno como programador, primero la capacidad de probar algo que normalmente no es posible probar en tu ambiente laboral.

Por ejemplo, en mi caso no hubiera comenzado a programar con nodejs  si un sábado no me hubiera puesto a buscar una solución de Comet usando websockets, ese sábado aprendí dos cosas importantes, usar la herramienta adecuada te puede ahorrar mucho trabajo (en este caso nodeJs y Socket.Io) y que no hay manera de criticar una tecnología si no conoces otras y encuentras esas diferencias por ti mismo.

En mi ambiente laboral meter una tecnología como nodejs(o ruby, o python) en un ambiente donde se usa .Net y Java, aumenta los riesgos de que el proyecto se complique y no se llegue a término, por falta de experiencia, porque no se ha implementado antes, o no hay gente capacitada. Pero si yo anteriormente ya hice uno o dos proyectos con esta tecnología, puedo echar por tierra los pretextos de la experiencia y capacitación, y para eso me ayude de otro petproject que hice en una tarde, donde use Nodejs y mongodb para una aplicación de mero entrenamiento y que a ultimas, al probarla en un entorno real, funciono sin problemas.

Experimentar con tecnologías o nuevas técnicas en los petprojects tiene un costo mínimo, lo único que hay que invertir es tiempo, a diferencia de otras profesiones, el programador puede fácilmente iniciar un proyecto, experimentar y eliminarlo como si nada hubiera pasado, un arquitecto o un ingeniero electrónico difícilmente pueden hacer eso, ya que requieren además de tiempo, invertir en material, equipo y muchas veces dependen de terceros para crear estos prototipos, un programador no tiene ningún impedimento en ese sentido.

También es interesante que algunos(que si no todos) los petprojects se liberen como open source, muchos de mis petprojects los puedes encontrar en github( http://github.com/majimenezp ) , no por el ego de mostrar tu creación, si no por 3 razones importantes:

  • Alguien puede aprender de tu camino recorrido, muchos petprojects son el inicio del acercamiento de una tecnología, alguien que también inicia y no tiene mucha experiencia puede aprender de tu código más fácilmente que algunos ejemplos que son mas demostraciones de features, adicional que puedes encontrarte con problemas que los creadores originales no habian previsto, como la compatibilidad con acentos en lenguajes como el español, o algun uso no previsto de la libreria que detona un bug
  •  Es un ejemplo más cercano a la realidad, por lo general un petproject resuelve algún problema trivial(un control de alta, bajas y cambios sencillo) y realiza acciones particulares, muchas veces estos ejemplos mas cercanos a la realidad son donde más se aprende, ya que se acercan a la experiencia real que tendrías al implementar esa tecnología en tu entorno laboral
  • A alguien le será útil, si ya resolviste el problema, quizás a otra persona también o por lo menos en un porcentaje, ese ahorro de tiempo e inversión es bienvenido por cualquiera, en mi caso personal me ocurrió con fulcrum(que es un clon de pivotal tracker en Ruby on Rails, https://github.com/malclocke/fulcrum);  resolvió el problema de tener un control de las actividades de los compañeros del area y acercándonos a un modelo agile, para quien lo creo quizás fue un petproject en su compañía y vio potencial y lo libero, para mi es importante porque resolvió un problema y comienzo aprender de ruby on rails con un ejemplo tangible y bastante interesante, adicional de que se implemento ruby en el entorno laboral y se comienza a ver como una alternativa de desarrollo
  •  Alguien puede ayudarte, al resolver el problema de alguien más, quizás el tenga detalles particulares que quiere resolver, y en el afán de adaptar tu petproject a su caso, agregue características que enriquecen tu proyecto, por lo tanto te beneficias tu y el se beneficia, tu ganas características en tu proyecto y el ahora tiempo y dinero al tener casi todo el problema resuelto, todos ganamos

 

 

Muchas veces no creamos estos proyectos o no les dedicamos un tiempo por distintos pretexto, por eso les propongo estas recomendaciones que les pueden ser útiles al momento de realizar un petproject:

  • Deja de jugar/ver televisión/ver series/etc, si tienes 3 o 4 horas diarias para ver televisión, jugar videojuegos o algo similar, a veces es mejor dedicarlas a tu proyecto personal, a la larga obtendrás una retribución en conocimiento que es mayor a la del entretenimiento.
  •  Sacrifica una hora de tu almuerzo, generalmente si tienes un horario cortado y te dan dos horas de comida, puedes hacer lo siguiente: Cuando requiero crear  una características o quiero dedicarle tiempo al proyecto, después del corte de medio día donde todos salen a comer, me despejo 5 minutos, traigo ya mi almuerzo de mi casa, como, eso me toma quizás 20 minutos y las 1.5 horas restantes las dedico a terminar esa características que quiero agregar a mi proyecto, cuando todos regresan de la hora del almuerzo, continuo con las actividades de mi trabajo habitual .
  • Aprovecha los lapsos muertos, a veces en el trabajo, depende de muchos factores, pero muchas veces tienes tiempos muertos a causa de esperas o retrasos causados por cuestiones ajenas a ti, aprovecha ese tiempo leyendo un blog relacionado con lo que estás haciendo, buscando librerías, ejemplos o herramientas que ayuden al petproject, o mejor aún, programando el proyecto. En lugar de estar  viendo youtube o mandando cadenas a los amigos en la oficina, mejor enriquece tus habilidades.
  •  Muestra lo que haces a tus compañeros del trabajo, a veces cuando muestras lo que hace tu petproject y resuelve el problema de alguien más, puedes conseguir un aliado importante no solo para intercambiar ideas o platicar sobre la tecnología, si no para también tener una crítica constructiva de lo que estás haciendo y apoyo al momento de proponer su uso en el ambiente laboral.
  •   No uses los fines de semana, los fines de semana son sagrados, úsalos para despejarte, descansar y dedicarlo a tu familia y amigos, el petproject no se va a ir y aunque los fines de semanas son atractivos para avanzar en el petproject a la larga vas a terminar mas desgastado y eso afecta tanto tu desempeño en tu trabajo formal, como en tu proyecto adicional.

Muchos somos de los que creamos un petproject y comenzamos bien e invirtiendo los ratos libres en hacerlo crecer.  Pero llega un momento donde se pierde ese “hype”, y el petproject muere, quizás porque resolviste el problema por otro medio, o simplemente te dejo de ser interesante, pero el objetivo de este tipo de proyectos no es meramente llegar al final, si no lo que importa es el camino recorrido y lo que logras aprender al salir de tu zona de comfort y experimentar con nuevas tecnologias.

 

27 Jul 2011

Aplicacion web con Nancy y Anna

Vamos a crear una pequeña app con el web microframework Nancy y vamos a hostearla en Anna, un http server que usa Reactive Extension para el procesamiento de los request.

La unica restriccion la momento de crear una aplicacion en este esquema es el tener que usar C# 4.0 (.Net Framework 4.0 complete client o Mono 2.8), ya que Nancy hace uso de dynamics, pero creo que es un buen pretexto para comenzar a usar esta version del framework en la oficina.

Rapidamente repasemos que es Anna y Nancy:

Anna (https://github.com/jfromaniello/Anna)
Es un http server que utiliza las reactive extension, de esa manera responder a los request de manera asincrona.

Nancy (https://github.com/nancyfx/nancy)
Es un web framework ligero para .Net, inspirado en sinatra su objetivo es crear aplicaciones web ligeras y rapidas.

¿Por que Nancy sobre el http server Anna?
Por que cuando comence a trabajar con Nancy, requeria hostear una aplicacion web dentro de un servicio windows, y que a su vez pudiera transportarla a mono sin problemas, aunque Nancy tiene un selfhosting, el soporte era limitado. Anteriormente habria probado kayak y manos de mono, que ofrecia una manera asincrona y mas rapida de administrar los request Http y queria utilizar algo similar para esa aplicacion, buscando en google encontre Anna y era exactamente lo que requeria, adicional a eso, @GrumpyDev hizo una prueba con Nancy y Anna y estaba funcionando muy bien, por lo cual es una buena alternativa para trabajar con Web en C# sin usar ASP.Net MVC+ IIS.

En la version 0.7 de Nancy el selfhosting fue mejorado,pero no lo he probado.

Ok para la comenzar,creamos una aplicacion de linea de comandos en visual studio.

Imagen01


Despues agregamos las referencias a las siguientes librerias:

  • Anna.dll
  • Nancy.dll
  • Nancy.ViewEngines.Razor.dll
  • System.Reactive.dll
  • System.Web.Razor.dll

Ya con las referencias agregadas, necesitamos crear una instancia del servidor web, para eso vamos a utilizar Anna. Para eso necesitamos inicializar el web server y devolver un mensaje cuando nos soliciten informacion:

Imagen02

Como se puede observar, Anna nos proporciona desde el inicio un esquema para responder a request http como GET,PUT,POST,HEAD,OPTION,etc. En este caso respondemos a un request a "/prueba" y solicitamos un parametro por medio de la url (parametro). Realizamos una prueba invocando la url:
http://localhost:9090/prueba/hola
Y nos devuelve lo siguiente:

Imagen03

Hasta este momento ya la aplicacion tiene un web server que no requiere algun tipo de instalacion o configuracion(adicional a definir con que hostname y puerto va a operar) y nos permite exponer ciertas funcionalidades de manera inmediata.

Ahora vamos a agregar a Nancy, para eso hay que implementar una serie de clases para "traducir" el request de Anna hacia Nancy y poder devolver informacion en el response desde Nancy hacia Anna.

Para eso hacemos lo siguiente, vamos a agregar tres clases:

  • RequestExtensions (quien traduce los request de Anna a Nancy)
  • NancyResponse (quien traduce los response de Nancy hacia Anna)
  • GenericSrvRootPathProvider (Nancy necesita que le indiquen donde estan ubicados los archivos por esta clase)

Primero veamos cual es el funcionamiento de la clase RequestExtensions

Imagen04

Esta clase es una extension para poder pasar los Request de Anna hacia Nancy, recibe un request de Anna y crea un Request de Nancy y pasa todo el flujo de bytes, los headers,y el metodo http enviado.

Ahora veamos el funcionamiento de la clase NancyResponse

Imagen05

Esta clase recibe un Response de Nancy, y crea un objeto Observable de Reactive Extension, y Anna se subscribe a este objeto para recibir la respuesta de Nancy, recordemos que Anna se basa en metodos Observables para el procesamiento de la informacion.

Por ultimo la clase GenericSrvRootPathProvider

Imagen06

Esta clase le indica por a Nancy donde se encuentra ubicada la aplicacion y donde esta el RootPath para obtener los archivos, es importante definirla ya que si no, los archivos de vistas y recursos como archivos de javascript,css o imagenes no van a poder ser enviados desde el servidor.

Ya con estas tres clases implementadas, hay que comunicar Anna con Nancy y para esto vamos a nuestra clase Program de nuestra aplicacion, y realizamos unos cambios.

Imagen07

Donde agregamos la inicializacion del BootStrapper para Nancy y del engine, despues agregamos un en Anna, que todos los request de manera directa(RAW)  y que correspondan a la url "/*" se procesen por medio de Nancy. Ademas comentamos el Metodo Get con el cual anna respondia request, ya que ahora todos van a ser enviados a Nancy.

Ahora para que nancy procese esta informacion es necesario crear un modulo de Nancy, para esto agregamos la clase MainModule:

Imagen08

Donde se puede ver la instruccion:

Get["/"] = x =>
{
    return "El servidor esta operando.";
};
Esto indica que Nancy cuando reciba un request de tipo Get, y que corresponda a ese patron de URL, lo va a procesar con la funcion que en este caso devuelve un texto.

Imagen09

Ahora por ejemplo en este caso:

Get["/Test/{parametro}"] = x =>
{
    var model = new { mensaje=x.parametro};
    return View["Test.cshtml",model];
};

Se recibe un request de tipo Get y se espera un parametro, los parametros los podemos indicar entre llaves, y dentro de la funcion se procesa, en este caso para hacer referencia a los parametros se utiliza la funcionalidad dynamic del C# 4.0.

A su vez, se crea un objeto de modelo, que se pasa a la vista Test.Cshtml,que es una vista de Razor. Actualmente Nancy soporta los siguientes view engines:

  • Razor
  • Spark
  • NDjango
  • DotLiquid

En este caso utilizamos razor, y al pasarle el parametro, la vista nos devuelve el texto enviado en el cuerpo del html.

Imagen10

Algo que tenemos que cuidar cuando utilizamos archivos dentro de estos proyectos, es habilitar la opcion de que se copien a la carpeta output(Copy to output directory) en las propiedades del archivo, ya que cuando realicen la ejecucion pueder que no esten los archivos en la carpeta correcta y por lo tanto no se procesen las vistas o no se muestre el css o las imagenes.

Imagen11

De esta manera podemos tener una aplicacion Web MVC sin problemas, que opere dentro de un executable, web services o dentro de otra aplicacion web de manera rapida y sencilla con un microframework.

El codigo fuente de la demostración: aqui

27 Jul 2011

C# y los web microframeworks

A diferencias de otros lenguajes como PHP,Ruby o Python, en .Net la evolucion(o involucion) de ASP.Net a venido de una estructura de controles ala desarrollo desktop a algo mas logico para la web, el paso de ASP.Net webforms a Asp.Net MVC a provocado que mucha gente que utiliza .Net como plataforma de desarrollo, adicional de la fuerte influencia de ruby on rails comience a ver ASP.Net MVC como algo muy "pesado" o que en muchos casos no compite con la escalabilidad de otras plataformas web.

Actualmente en el ambiente de .Net se ha dado una nueva ola de microframeworks web como:

Ademas de eso, mucha gente esta trabajando en un estandar para el hosting de aplicaciones web, de nombre OWIN(http://owin.org/) que viene siendo algo similar a lo que existen en Ruby(Rack) o Python WSGI, un estandar del como las aplicaciones web se deben comunicar con el servidor web, desde la parte de hosting y administracion, asi como su governance y demas.

Actualmente existen distintos proyectos que integran el draft que existe de OWIN:

Web servers (o algo similar a web server):

Y de momento los microframeworks que soporta OWIN:

  • Nancy
  • ServiceStack(en progreso)

La necesidad de estos microframeworks, o por lo menos en mi caso, creo que se debe a las siguientes razones:

Web en .Net != ASP.Net

El crear un proyecto con C# usando .Net siempre ha estado ligado al uso de ASP.Net, y siendo que el Microsoft Stack se basa en IIS para el hosting de la web ya sea webforms o MVC, muchas veces no requerimos todas sus funcionalidades o peor aun, resulta extremadamente lento a comparacion con soluciones en otras plataformas de desarrollo. Al fin al cabo, podriamos hostear las paginas html en un servidor web cualquiera y que este por medio de peticiones Ajax o en el mejor de los casos websockets de Html5 con un backend hecho en .net que responda por http o tcp/ip. El desarrollo en C# necesita despegarse de la dependencia de un web server(en este caso IIS) para funcionar en varios entorno utilizando quizas OWIN como estandar.

Hosting autocontenido

Relacionado con la razon anterior, muchas veces se requiere que ciertos servicios de backend implementados dentro de servicios, daemons o aplicaciones autonomas, tengan cierta interface web no solo de administracion, quizas exponers servicios SOA. Ademas que no se puede estar realizando instalaciones de webserver que soporten asp.net por cada aplicacion, se requieren ambientes donde no se requiera instalar nada.

C# no solo esta en windows

En varias ocasiones se requiere que un servicio de backend corra en Linux o alguna otra plataforma *nix, por lo cual usar mono es una opcion bastante atractiva e implica poca reigenieria a la aplicacion, tener un modo de hostear la aplicacion, y que esta aplicacion tenga cero dependencias de un web framework que esta pegado al OS (Windows) puede hacer mas atractiva y a la larga mantenible un aplicacion. ASP.Net MVC y webforms actualmente corren sobre linux utilizando mono, pero siempre existen pequeños detalles que hay que ajustar, por lo que tener un web framework que funcione sin tener que hacer ajustes, es algo muy util.

¿Realmente estoy usando todo el web framework actual?

Actualmente la mayoria de las aplicaciones que se he hecho en ASP.Net MVC y lo mismo en ASP.Net webforms han comprendido controles para procesos aislados en empresas, que mas o menos tienen las siguientes caracteristicas o modulos:

  • Seguridad
  • Catalogos
  • Pantallas de captura o transaccionales
  • Pantallas informativas
  • Administracion de alguna opciones del sistema
  • El control interno de los permisos para acceder pantallas o caracteristicas

Como se puede ver, de esas caracteristicas creo que las funcionalidades de un framework web como asp.net mvc o webforms las cubren sin problemas, el problema(u objetivo) de los frameworks de ASP.Net es lograr cubrir un amplio espectro de las necesidades que surgen con la creacion de una aplicacion web(seguridad, intercambio de informacion con el server, generacion de controles o inputs), y hay casos donde requerimos resolver un problema particular con algo muy sencillo, entonces esas caracteristicas adicionales se convierten en un lastre como pasa con el caso del viewstate en algunas aplicaciones que creaban controles dinamicos en webforms o el caso del abuso del almacenamiento de informacion en las sesiones.

La web es HTML, no controles

Los desarrolladores de PHP, Ruby o Python siempre han estado mas cerca del html que los desarrolladores .Net, por lo menos es el caso de la mayoria de los desarrolladores. Muchos programan con el drag n' drop way en el caso de webforms, arrastran y suelta controles como en las aplicaciones desktop y esto ha provocado que muchos desarrolladores se alejen de la verdadera base del desarrollo web. ASP.Net MVC logra regresar al desarrollador al HTML pero aun desconoce como se comportan muchos elementos que forman parte del desarrollo web, cookies, el control de la autenticacion, cache, etc. Un framework grande ha logrado abstraer ciertas tareas que en algunos casos creo que es necesario conocer o saber como funcionan y en eso los desarrolladores en otras plataformas nos llevan ventaja. Creo que como desarrollador, la web no debe ser una pantalla de diseño como sucede con webforms, si no que el desarrollador debe entenderse con el HTML y como se hace en otras plataformas de desarrollo.

No es escalable

Para escalar una aplicacion de ASP.Net ya sea MVC o Webforms, la unica manera es utilizar una granja de servidores de IIS e implementar ciertos mecanismo, si uno tiene el control tanto de la capa de hosting como de la capa del web framework, es capaz de implementar una aplicacion escalable y aprovechar mucho mejor los recursos de hardware de los cuales se disponen.

 

La idea de usar un web microframework no es solo por verse l33t si no para poder aprovechar mejor los recursos disponibles, implementar soluciones que no requieran tanta ceremonia para implementarse (tener iis,configurar app pools, seguridad, etc) y aumentar su portabilidad. Por ultimo implementar soluciones completas y robustas donde nos el tiempo invertido sea para desarrollar lo especificado y no para hacer funcionar o integrar los componentes, o entender como hacer algun tipo de truco con el framework. 

 

 

7 Jul 2011

Los stored procedures son de los noventas

En los distintos trabajos donde me he desempeñado,siempre me encuentro con el eterno debate del uso de stored procedures, principalmente en el ambiente de .net.

Creo que esto se ha venido debatiendo en el mundo .netero desde la creacion del mismo(2002) y una prueba de ello es este post de Jeff Atwood de codinghorror:

http://www.codinghorror.com/blog/2004/10/who-needs-stored-procedures-anyways.html

Donde expone el por que es un dolor de cabeza el usar stored procedures en una aplicacion:

  1. Los lenguajes de stored procedures(T-sql o PL/sql) son viejos y arcaicos, y tienen muchas cosas raras propias de las bases de datos, ademas de carencia de funcionalidades derivadas de compatibilidad con versiones anteriores,que dificultan escribir logica de negocio.
  2. Los stored procedures por lo general no se pueden debuggear desde el mismo IDE donde escribes codigo(Visual studio en el caso de .Net), cuando hay un error hay que pasar por un proceso de identificacion y aislamiento del error cuando hay stored procedures involucrados.
  3. No proveen mucha retroalimentacion, es decir muestran que existe un error y nada mas, y alguna veces aunque dicen la linea del error, no necesariamente coinciden.
  4. Los stored procedures no reciben objetos, si necesitas pasar informacion es por parametros, facilmente llega uno a tener stored procedures de 10 o 15 parametros.

Ahora las razones por las cuales,segun quienes apoyan el uso de stored procedures son las siguientes:

  1. Performance, por que la base de datos optimiza el acceso a datos por medio del execution plan y lo mete en cache para uso posterior.
  2. Pueden ser asegurados individualmente y al cliente solo se le dan permisos para usar ese stored procedures y no las tablas.
  3. Son mas faciles de mantener, por que se modifica el stored procedure y no un hard-coded sql
  4. Añaden un nivel extra de abstaccion para delimitar las capas y aislan los detalles de implementacion y estructura de la db hacia los clientes
  5. Reducen el trafico de red,por que los sql se ejecutan en lotes y no se envian multiples request desde el cliente.

 

Ahora en base a mi experiencia puedo decir lo siguiente:

Usar stored procedures para logica de negocios no es conveniente, por que, un ejemplo:

Teniamos un sistema, un metasistema, el cual la logica de negocios se escribia en javascript o PL/SQL, un dia por cuestiones de licenciamiento(Oracle vende caro su amor) decidieron mandar a freir esparragos a Oracle, el problema era, 30 sistema que operaban sobre este metasistema, habria que pasarlo a sql server(y hubiera sido el mismo caso de pasarlo a mysql,sqlite o postgresql).

Pasar aproximadamente 300 stored procedures de PL/SQL o T-SQL no era una tarea trivial, ademas existian varios que tenian una complejidad bastante grande, pero a ultimas se estimo que se tardarian 6 meses con 2 personas en migrar estas funcionalidades, el problema a nivel gerencial era sencillo: ¿Quien iba a pagar esto?.

La mala decision al momento de crear el sistema y abstraer la logica de negocios en stored procedures provoco que el sistema no sea escalable, ahi es donde voy al siguiente punto.

 

Los stored procedures no escalan bien.

Imaginen que tienen una base de datos con stored procedures, dicha base de datos se tiene replicada en distintos servidores, como sabe el stored procedure a donde tiene que ir a tomar los datos, o en estructuras de maestros-esclavos, como sabe el stored procedure que la tabla que debe impactar esta en el master y solo debe leer de los esclavos. Habria que programar esa logica en el stored procedure, y creo que ese tipo de lenguajes no esta diseñado para operar a esos niveles. Ademas que si tienes un grid de bases de datos en distintos puntos en la red, se lleva al traste el punto 5 de la ventaja de usar stored procedures(hay intercambio de datos sobre la red  y no creo que se realice en lotes).

SQL no es un lenguaje de programacion

SQL es un lenguaje de queries, no para programar,intenten programar validaciones o una serie de formulas que involucren usar datos de distintas fuentes. Eso por lo menos invalida el punto 1 sobre el perfomance.

El cliente no ve la base de datos(o no debe ver).

Si un cliente o usuario esta viendo la base de datos, entonces tienes un serio problema con la aplicacion, los unicos que deben de ver la base de datos es la aplicacion, si pretendemos dar acceso a alguien por medio de un stored procedures a una tabla de nuestra base de datos, seria mas facil exponer un servicio REST, ODATA o un webservice,donde realmente se pueda controlar el acceso a la informacion. Es como invitar a alguien a tu casa y decirle que solo puede estar en la sala de television,no es tan seguro que digamos. Por lo menos el punto 2 y 4 no creo que sean tan validos.

 

Si agregas o quitas un campo de la tabla, nada mas cambias el stored procedure.

Si realizan una accion como esta, el stored procedure va a tronar, de ninguna manera automagicamente se va arreglar o evitar que esto suceda, adicional a esto tu aplicacion va a tronar tambien, por que cuando se invoque el stored procedure va a marcar un error y no va a devolver absolutamente nada.

Es decir, tengo que cambiar el stored procedure y ademas cambiar mi aplicacion, asi que por lo menos el punto 3 se tira por tierra y el punto 4 pierde cierta fuerza.

Adicional a lo anterior si usas un ORM como subsonic, massive  o autogeneras las clases con un template de T4 o una aplicacion para nhibernate o petapoco, cambiar la estructura es algo que no quita mas de 10 minutos el realizar, y por lo menos no tengo que mantener otro codigo en otro lenguaje.

No todos usan stored procedures

Otra razon de por que no usarlos es que muchas bases de datos no implementan stored procedures, sqlite y mysql antes de la version 5, y las bases de datos NoSQL tampoco. Por lo que si tu aplicacion o producto se espera que funcione con distintas bases de datos o arquitectura, en definitiva la logica de procesamiento de datos o negocio, no puede estar en la base de datos.

 

Los stored procedures no se autogeneran.

Existen herramientas para autogenerar stored procedures, para tareas de CRUD. Pero muchas veces eso lo evitamos por medio de un ORM, y tenemos el mismo nivel de abstraccion.

 

En resumen, las razones por que usar stored procedures no es una buena idea:

  • Dependes de un lenguaje que esta en tu repositorio de datos, si el repositorio de datos cambia, se tendra que reescribir el codigo
  • Este lenguaje mucha veces esta amarrado a la version de la base de datos, si realizas un upgrade,lo mas seguro que haya cambios o se tenga que reescribir codigo
  • El mantenimiento es a veces peor con los stored procedures,ya que si existen varias instancias de las bases de datos, se requiere implementar en distintos lugares
  • Es complicado implementar un control de versiones para los stored procedures,por lo cual dar seguimiento a los cambios es dificil
  • Es complicado realizar pruebas unitarias a stored procedures o usar un esquema de test driven development o behavior driven development(en caso de que en tu proceso de desarrollo lo utilices)

Usando un  ORM puedes conseguir un buen nivel de abstraccion e incrementar la productividad al no tener que generar codigo SQL, adicional a esto muchos ORM logran hacer un poco mas agnostico el trata con una base de datos, permitiendo cierta facibilidad y flexibilidad al momento de hacer migraciones a otros repositorios de informacion.

Con la velocidad de las redes y los mismos drivers o conectores en los distintos lenguajes de programacion, la cantidad de tiempo que se tarda en intercambiar la informacion usando la red, es una cantidad despreciable que en sistemas dentro de una empresa, que son usados por 30 o 50 personas, no tiene un gran impacto.

Por lo anterior creo que usar stored procedures solo aplica cuando se realizan tareas de transformacion o administracion de la informacion, algun analisis o generacion de informacion de manera programada, pero algo como hacer insert,updates y deletes no creo que tenga mucho caso hacerlos, y mas si esos procesos involucran logica de negocios.

 

 

 

Miguel Angel Jimenez Perez's Space

C# developer, Jquery user