Mover mensajes entre colas de MSMQ

Trabanjando con MSMQ a menudo nos encontramos con escenarios en los que necesitamos mover todos los mensajes de una cola de MSMQ a otra. Por ejemplo yo me he encontrado con la necesidad de mover los mensajes desde una cola de mensajes ‘poison’ a la cola a la que estaban destinados originalmente para que sean reprocesados.


Existe una manera obvia de mover todos los mensajes de una cola a otra, enumerarlos y volverlos a enviar a la cola original. Pero existe otra manera mucho más eficiente (según las pruebas sencillas que he podido hacer) y menos conocida: utilizar la interfaz IMessageMover de la COM+ Service Type Library, en concreto su método MoveMessages, que mueve todos los mensajes de una cola a otra, además lo hace de manera transaccional si las colas son transaccionales.


Para usar esta interfaz basta con añadir una referncia a la librería COM+ Service Type Library.


image


Como esta interfaz es olecompatible, tal y como podemos observar con Oleview (imagen siguiente), .Net la puede utilizar sin ningún problema, de manera totalmente transpararente.


image 


Os dejo un poco de código de ejemplo que muestra lo simple que es realizar el movimiento de los mensajes entre colas:



  using COMSVCSLib;


 


  …


 


  IMessageMover messageMover = new MessageMover();


  messageMover.SourcePath = @”.PRIVATE$ColaOrigen”;


  messageMover.DestPath = @”.PRIVATE$ColaDestino”;


  messageMover.MoveMessages();


 


  …


 


¡Espero que os resulte útil!

Cómo cazar una fuga de memoria en .Net (I)

Hablaba en un post anterior de como me las he tenido que ver con una fuga de memoria en .Net recientemente, e incluso ponía un pequeño caso mínimo representativo del problema que he tenido. Hoy toca hablar de como llegue a la conclusión de que estaba ante una fuga de memoria y a la conclusión de que se trataba de una fuga de memoria manejada.

Para diagnosticar una fuga de memoria en .Net debemos comenzar por responder dos preguntas, que a continuación veremos. Si diré que la herramienta para contestar ambas preguntas es el monitor de rendimiento.

La primera cuestión que tendremos que dilucidar es: ¿Estamos ante una fuga de memoria o ante un consumo excesivo de memoria?

No es extraño encontrar aplicaciones de .Net que por un mal diseño hacen un uso excesivo de memoria. Una situación habitual es por ejemplo, convertir la sesión de las aplicaciones Asp.net en un cajón de sastre en el que todo cabe y en el que se acumula un motón de información que lógicamente tiene un coste en consumo de memoria. Pero esto es diferente de una fuga de memoria y tiene mejor solución: añadir más memoria a nuestro servidor puede ser una medida paliativa suficiente e incluso más rentable, en términos económicos, que dedicar esfuerzo a optimizar el consumo de memoria. Cuando nos enfrentamos a una fuga de memoria la solución de añadir más memoria al servidor solo es prolongar la agonía.

Para saber si estamos ante una fuga de memoria debemos observar los bytes privados del proceso sospecho. Para ello basta establece una traza del monitor de rendimiento que recoja la evolución del contador de bytes privados que se encuentra en la categoría proceso.

El contador Proceso/Bytes privados recoge el número de bytes que nuestro proceso ha reservado y que no pueden ser compartidos con ningún otro proceso. Por lo tanto si nuestro proceso se está guardando memoria de manera egoísta este contador será nuestro chivato.

Si tras un periodo de muestreo razonable (lo que es razonable depende de la naturaleza de las actividades que lleve a cabo el proceso) vemos que la tendencia de ese contador es siempre creciente, sin duda nos encontramos ante una fuga de memoria. Si este contador no muestra una tendencia creciente, aunque sea elevado o puntualmente elevado, no nos encontraremos ante una fuga de memoria.

Fijaros en la traza de bytes privados que dejaba el servicio en el que yo sufría la fuga de memoria.

Bytes privados

Viendo esa traza de casi dos días se hace evidente que estamos fugando memoria, sobre todo teniendo en cuenta que como ya comenté, con el paso del tiempo, acababa sufriendo un ‘casque’.

La segunda cuestión a desvelar es: ¿Se trata de una fuga de memoria nativa o manejada?

Sin duda saber si lo que estamos fugando es un recurso no manejado o una manejada nos va a dar muchas pistas sobre donde hemos de buscar en nuestro código la fuga de memoria.

Para esto vamos a usar otros dos contadores, que nos dan, para el caso que nos ocupa una información similar: cuanta memoria se está consumiento en la pila manejada del proceso (Memoria de .Net CLR/# Bytes en todos los montones)  y cuantas colecciones de generación 2 tenemos (Memoria de .Net CLR/# de colecciones de gen. 2), es decir cuantos objetos de nuestro proceso están sobreviviendo durante demasiado tiempo al recolector de basura. Al final los estos dos contadores nos informa de si estamos dejando atrás recursos maneajados sin liberar.

Logicamente, si estos contadores crecen de manera paralela a los bytes privados de nuestro proceso, estarémos ante una fuga de memoria manejada, sin embargo si crecen los bytes privados pero no crecen los bytes en la pila manejada lo que estaremos fugando es un recurso no manejado.

En la siguiente imagen podéis ver que en el caso que a mí me ocupaba claramente estabamos fugando memoria manejada, pues hay una clarísima correlación entre los tres contadores.

Bytes privados vs Bytes .Net

Ahora ya tengo claro que estoy fugando memoria y que es memoria manejada ¿que puedo hacer?.

Básicamente tengo dós opciones, usar WinDBG para ir obtieniendo la situación de la memoria de mi proceso y ver que objetos son los que estoy fugando opción que David Salgado explico explendidamente y que exije un dominio de WinDBG notable o usar una opción para meros mortales: el CLR Profiler.

WinDBG es una herramienta potentísima y que sin duda todo desarrollador que quiera poder resolver problemas peliagudos con aplicaciones de Windows tiene que saber manejar. Cuando las cosas se ponen realmente feas, WinDBG es nuestro mejor aliado y a menudo el único que nos puede sacar de atolladero. Os recomiendo los post sobre WinDBG de mi compañero en Plain Concepts, Pablo Alvarez (el tiempo que paso en Microsoft dando soporte ha dejado su huella), y los de David Salgado sobre el mismo tema. Otro recurso impresionante, eso sí en inglés, sobre depuración en .Net con WinDBG son las .NET Debugging Demos de Tess Ferrandez, Escalation Engineer en Microsof Suiza.

En un próximo post, veremos como usé el CLR Profiler (opte por la opción facil) para diagnosticar donde, exactamente, se estaba produciendo la fuga de memoria.

Si queréis aun más información sobre los temas tratados en este post, os dejo la siguiente lectura recomendada:

Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework I y II 
Investigating Memory Issues

Identify And Prevent Memory Leaks In Managed Code
.NET Debugging Demos Lab 3: Memory
.NET Debugging Demos Lab 3: Memory – Review

Fugando memoria con .Net

Una de la grandes maravillas de los lenguajes manejados es que es imposible fugar memoria… al menos en teoria. Pero la verdad es que aunque es mucho más dificil fugar memoria, no es imposible. Es imposible fugar memoria en el sentido clásico del termino, en el sentido de reservar memoria, con un new, un malloc, un SysAllocString, etc y no recordar liberarla con el correspondiente delete, free, o SysFreeString, algo muy común en C o C++, esta es la buena noticia y es más por si sola justifica el uso de lenguajes manejados. Buscar fugas de memoria puede ser muy divertido, pero, desde luego no es lo más productivo que podemos hacer como desarrolladores.


La mala noticia es que nada nos libra de otro tipo de fugas de memoria, igualmente perniciosas pero, cierto es, mucho menos frecuentes, por citar algunos ejemplos: podemos añadir objetos a una colección que actue de cache y nunca sacar objetos de manera que la colección crezca indefinidamente (esta fuga suele ser facil de cazar…) o algunas un poco más sutiles como el ejemplo que hoy propongo. Otra forma habitual de fugar memoria en .Net es cuando se utilizan recusos nativos mediante COM Interop o P/Invoke.


Hacía bastantes años, desde que deje Panda Software y la programación en C/C++ y COM que no me enfrentaba a un caso serio de perdida de memoria. A pesar de haber escrito mucho código en .Net. Pero desde hace algún tiempo un proyecto en el que estoy trabajando presentaba una seria perdida de memoria en un servicio que se ejecuta de manera continua antendiendo peticiones del resto de componentes de la aplicación. El resultado es que al cabo de una semana y tras agonizar durante un día en condiciones de baja memoria, en un servidor de producción con 4Gb de memoria, la aplicación cascaba con una agónica OutOfMemoryException. Las entradas en el registro de eventos eran bastante elocuente (esta es un ejemplo de una de ellas, pero variaban según el componente que tratase de hacer la asignación de memoria ‘definitiva’):


EventType clr20r3, P1 AppQueFuga.exe, P2 1.0.0.137, P3 45d6968e, P4 mscorlib, P5 2.0.0.0, P6 4333ab80, P7 116e, P8 29, P9 system.outofmemoryexception, P10 NIL


Buscar fugas de memoria siempre me ha apasionado, es un tipo de bug realmente interesante, y la verdad me ha traido grandes recuerdos…


El reto que os planteo hoy es ¿alguien sabe por qué el siguiente código, caso mínimo extraido desde le problema real y a simple vista totalmente inofensivo, fuga memoria?. Para ver que fuga memoria solo tenéis que compilar el código (lo tenéis como adjunto a este post), ponerlo a ejecutar y ver el consumo de memoria del proceso. Fijaros que solo uso clases manejadas, lo que hace aun más interesante esta fuga de memoria:




using System;


using System.Diagnostics;


 


namespace Leaker


{


  static class Leaker


  {


    public static TraceSwitch CurrentTraceSwitch


    {


      get { return new TraceSwitch(“Test”, “Test”, “Test”); }


    }


  }


 


  class Program


  {


    static void Main(string[] args)


    {


      //Bucle infinito


      while (true)


      {


        //Cada vez que se ejecuta esta línea perdemos memoria


        Console.WriteLine(Leaker.CurrentTraceSwitch.Level);


      }


    }


  }


}


En proximos post voy a comentar cómo diagnostique esta fuga de memoria y daré la solución a por qué se produce, estad atentos, os aseguro que será interesante.

Uso de metologías ágiles en Microsoft

Por casualidad he encontrado un intersante documento de Andrew Begel sobre el estado de las percepciones y el uso de metodologías ágiles en Microsoft. El documento es bastante interesante y se puede descargar desde aquí: Perceptions of Agile Software Development at Microsoft.

Sin duda lo que más me ha llamado la atención es la satisfación que declaran los implicados en proyectos ágiles, tal y como se puede ver en el diagráma de abajo:

Agile methodologies results at Microsoft

Más del 60% de lo encuestados declaran que las metodologías ágiles funcionan bien para ellos y su equipo y el mismo porcentaje declara que las metodologías ágiles han mejorado como colaboran desarrolladores y probadores.

Los beneficios de las metodologías ágiles más destacados por los encuestados son:

  • Mejor comunicación y coordinación
  • Entregas más rápidas
  • Diseño más flexible – Respuesta al cambio más rápida
  • Proceso más razonable
  • Incremento de la calidad
  • Mejor enfoque en el cliente
  • Desarrollo más centrado – Mejor priorización
  • Mayor productividad
  • Mejor moral
  • Testeo a priori

Otro aspecto interesante del documento es ver las metodologías ágiles más usadas:

Agile Methodologies at Microsoft

A la vista del estudio se hace patente que dentro de Microsoft los resultados son muy similares a los de otras encuestas o estudios similares.

Scrum: Asi empezo una revolución

imageQue Scrum está revolucionando la manera en la que desarrollan software millones de equipos de desarollo en el mundo es algo que ya nadie duda. Ninguna otra metodología se ha ganado el favor de los desarrolladores tan rápido y cada vez más empieza a ganarse el favor de otros roles implicados en las empresas de desarrollo de software como gerentes, comerciales o departamentos de marketing. Evidentemente si algo hemos aprendido en la industria del software es que no hay balas de plata y que nos movemos mucho por modas, pero Scrum sin duda ha llegado para quedarse.


Todo empezo con la publicación en 1986 por parte de Takeuchi y Nokada de un documento titulado The New New Product Development Game. Seguro que estos dos profesores desdicados al estudio de la gestión en los negocios no tenian ni idea de que años más tarde, Ken Schwaber y Jeff Sutherland iban a tomar, las ideas centrales del documento comentado para desarrolla una nueva manera de gestionar proyectos de construcción de software, inciando una ola que ya parece imparable.


Hoy traigo a este blog este documento (como adjunto a este post) gracias a que uno de los alumnos de uno mis cursos de gestión de proyecto me amablemente me lo ha enviado por correo. Sin duda un documento de interés para cualquiera que esté interesado en Scrum.


En este artículo fundamental para el nacimiento de Scrum, los autores comparan la tradicional aproximación secuencial de desarrollo de productos en el que consecutivas fases del desarollo son llevadas a cabo por diferentes grupos de especialistas (similar al desarollo en cascada) con un enfoque más iterativo, en el que, usando una metáfora basad en el rugby, solo una persona corre en cada momento y el equipo pasa el balón al siguiente corredor. El liderazgo del proyecto va cambiando y todos trabajan como un equipo.


Takeuchi y Nokada proponen un nuevo enfoque holístico en que las fases del desarrollo se solapan y todo el proceso es llevado a cabo por un equipo multifuncional de manera similar a lo que ocurre en el rugby donde todo el equipo trata de avanzar moviendo el balón. El documento no habla del desarrollo del softwar sino que estudio el desarrollo de productos de automocion, hardware o impresoras.

WIWA :: Work Items Web Access

La principal novedad de Visual Studio Team System 2008 en lo relativo a licencias es la posibilidad de que usuarios sin una CAL trabajen con work items. La idea es permitir que servicios de soporte al usuario, comerciales, usuarios o cualquier otro rol similar pueda informar de bug, sugerir nuevos requisitos o en general realizar cualqueir actividad en la que solo trabaje con work items creados por el mismo.

Para facilitar este tipo de escenarios, Microsoft ha liberado una herramienta basada en Team System Web Access que nos ayuda en este tipo de escenarios.

Como usuario sin una CAL de TFS, se puede utilizar WIWA para:

  • Crear nuevos work items.
  • Editar work items creados por tí.
  • Ver la lista de work items creados por tí.

Las actividades que no se podrán realizar desde WIWA pues como usuario sin CAL supondrían una violación de la licencia son:

  • Ver work items creados por otros.
  • Listar, ver, editar o ejecutar consultas de work items.
  • Añadir, editar o eliminar enlaces de los work items, excepto adjuntos e hipervinculos.
  • Acceder a documentos almacenados en el portal de proyecto (no entiendo esta limitación pues la licencia de WSS es libre).
  • Acceder a los informes del proyecto (siempre se podra hacer desde el sito de Reporting Services o desde el portal del proyecto).
  • Acceder a l gestor del fuentes
  • Trabajar con builds

Sin duda la gran ventaja que WIWA aporta es que simplifíca el escenario de la gente que solo accede a TSWA solo para reportar bugs y además nos reduce el número de licencias necesarias.

Podéis descargar la CTP de Work Item Web Access 2008.

Excelente herramienta para trabajar con colas de MSMQ

He descubierto, gracias a un compañero de proyecto, una excelente herramienta para trabajar con colas de MSMQ, con capacidades muy superiores a las que nos brinda la consola de administración de windows. La herramienta se llama QueueExplorer. Esta herramienta no es gratuita pero su coste es muy ajustado y además podemos descargar una versión de evaluación totalmente funcional (eso sí limitada en el tiempo).

¿Qué por que me gusta esta herramienta?

Con la llegada de WCF y la facilidad que esta tecnología nos da para trabajar con MSMQ y la proliferación de las arquitecturas dirigidas por eventos en las que la infraestructura de colas suele ser elemento indispensable, MSMQ es una tecnología que ha ganado muchísima relevancia en los últimos tiempos. De los proyectos en los que últimamente he estado implicado son muchos los que usan colas de MSMQ en su implementación.

En estos proyectos he sufrido algunas de las limitaciones de la consola de administración de Windows en lo relativo a trabajar con colas: por ejemplo la imposibilidad de inpeccionar mensajes completos (solo muestra los primeros 260 bytes), o la imposibilidad de cambiar ciertas características de los mensajes, como la caducidad, o la imposibilidad de mover facilmente mensajes entre colas, caracteristica indispensable para depurar con facilidad situaciones en las que terminamos con mensajes en colas ‘poison’ etc…

QueueExplorer es la solución a estas limitaciones. Esta excelente y ligera aplicación nos permite hacer todo lo que nos permite hacer la consola de administración y un motón de cosas más:

Una característica muy interesante para hacer pruebas bajo carga de nuestra aplicación que presenta esta aplicación es la posibilidad de realizar de manera masiva el envio de mensajes:

Otras características a destacar son:

  • La posibilidad de hacer backup del contenido de las colas
  • La posibilidad de gestionar colas de manera remota
  • Ver en detalle el cuerpo de los mensajes y guardarlo
  • Cortar, copiar y pegar mensajes entre colas
  • Modificar todos los aspectos del mensaje
  • etc…

En definitiva una herramienta casi indispensable si usas MSMQ en tus aplicaciones.

Además de esta herramienta, que aunque barata (de 49$ a 69$ según el número de licencias) tiene un coste, los desarrolladores de esta herramienta ha puesto a disposición del público una serie de herramientas de línea de comandos gratuitas que también son muy útiles: MQDelele, MQCopy, MQSave y MQBackup. ¡Indispensables!

Si las hubiese conocido antes me hubiese ahorrado escribir algún que otro script de PowerShell para limpiar colas… 😛

La falacia de la industrialización del desarrollo de software

Desde que escribí mi primera línea de código, hace ya unos cuantos años, siempre he percibido un ruido de fondo en la industria del software. Un ruido continuo y pertinaz. Un ruido que como un murmullo que vive entre las líneas de código dice: ‘el desarrollo de software es una actividad industrial’. Parece que hay mucha gente que está convencida de esto, que a mí me parece una falacia. Y que nadie piense que uso aquí la palabra falacia con un signifacado relajado, lo uso con todo su significado, según la RAE: ‘Engaño, fraude o mentira con que se intenta dañar a alguien’. Numerosísimas empresas trantan de hacernos creer que los desarrolladores somos meros peones intercambiables, piezas remplazables de una cadena de montaje, minusvalorando nuestra labor y dañando nuestras legítimas aspiraciones de reconocimiento profesional y económico. Y creo que se trata simplemente de no querer repartir el pastel, pero esta es otra historia. Creo que es hora de asumir que esta es una ingeniería en la que el valor está en sus profesionales más que en ningún otro aspecto y sobre todo una ingeniería que debe comenzar a trazar su propio camino.

Hay una serie de razones por las que a mí me parece evidente que si bien la ingeniería del software es sin duda una ingeniería (necesita del ingenio más que ninguna otra) es radicalmente diferente de la ingeniería industrial o la arquitectura u otras ingenierías digamos clásicas.

Es por eso que cualquier metáfora en la que se usen símiles con otras ingenierías es dañina en mi opinión y en la opinión de muchísimos otros miembros de la comunidad más relevantes que yo. Existe una gran controversia sobre este tema y como nó, me gustaría añadir mi granito de arena o más leña al fuego según como se mire.

Mi amigo Ibon Landa hablaba sobre esto a raíz de un anuncio de una empresa en dotNetMania y mucha gente me ha preguntado mi opinión sobre el tema, supongo que como consecuencia del revuelo que se armo cuando comenté otro anuncio anterior de la misma empresa, pues aquí va este post, en el que trato de explicar porque considero la ingeniería del software diferente a otras ingenierías y el desarrollo de software algo difícilmente industrializable.

Aunque considero que existen muchos motivos por los que el desarrollo de software es diferente voy a comentar los que me parecen mas relevantes:

En el desarrollo de software no es económico hacer todo el diseño y la especificación a priori

Diseño de Gaudi Cuando se trata de construir miles de vehículos tiene un gran sentido hacer una fortísima inversión en diseño y especificación a priori. Esta fortísima inversión se recupera diluyéndola en el coste de la gran cantidad de instancias de ese diseño que se van a implementar. En software esto no es cierto. De un diseño solo se hará una implementación (por mucho que se vendan millones de cds con ella) solo tendremos una instancia de un diseño determinado.

Otra diferencia importante es que el software no se puede construir principalmente uniendo elementos que ya existen. Durante un tiempo se pensó que si, incluso es algo que se persigue constantemente primero con el software construido mediante componentes y luego mediante el software construido orquestando servicios. Aunque ambos enfoques han ayudado a mejorar como se construye el software ninguno de los dos no libra de que todo proyecto tenga más líneas de código nuestras que ajenas. En la construcción de un coche, un barco, un avión o un edificio, lo que se reutiliza es mucho más significativo que lo que se construye de cero. Esto hace que, a igual magnitud del proyecto, el software sea mucho más difícil de especificar que un coche, un edificio o un barco: no podemos ahorrarnos diseño simplemente diciendo aquí se usa una capa de acceso a datos DIN 5722, sin embargo este enfoque es constante en la industria y la construcción.

Durante años se nos ha vendido que era posible la reutilización a gran escala, incluso se nos ha vendido herramientas 4GL que hacían de la especificación y el diseño a priori el enfoque primordial de desarrollo, pero sin duda los compiladores generalistas siguen siendo la principal herramienta de desarrollo. Si bien es cierto que cada vez se hace más uso de herramientas estilo DSL, estás no ha solucionado el problema de manera completa.

Con independencia del diseño que se haga a priori, cada línea de código que se escribe exige actividades de diseño. Sin embargo en otras ingenierías las actividades de construcción no implican tomar ninguna decisión sobre el diseño. El simple hecho de elegir el tipo de una variable numérica es una decisión de diseño. Solo los artistas toman tantas decisiones de diseño como los programadores cuando construyen algo, quizás por eso somos muchos los que pensamos que programar es un arte.

El entorno cambia constantemente

Cuando alguien se plantea construir un puente o un barco conoce de antemano el problema que va a solucionar. Este problema permanece constante en el tiempo. Esto no ocurre con el software. Los clientes a menudo necesitan saber que somos capaces de hacer antes de conocer realmente que es lo que quieren hacer. Nadie opina sobre el diseño de un puente porque reconstruir uno de sus tramos es sumamente costoso y rara vez hay valor alguno en esa reconstrucción. Sin embargo cuando un cliente, o un usuario ve un software, siempre se le ocurren maneras de cambiarlo para lograr obtener más valor. Evidentemente esto exige nuevas maneras de relacionarse con los clientes.

Además las herramientas , los lenguajes, las necesidades de calidad, los requisitos de rendimiento cambian, como mínimo, de proyecto a proyecto. En este entorno es poco interesante centrar tus esfuerzos en realizar un proceso repetible, es mucho más interesante buscar un proceso flexible. Esto no se da de manera tan clara en la industria o en el resto de ingenierías, el proceso básico de construcción de puentes y sus diseños no han cambiado desde la época de los romanos. Todos los puentes, por poner un ejemplo, tienen requisitos esenciales muy similares: unir dos puntos salvando un obstáculo. ¿Alguien podría hacer una descripción similar de los proyectos de software?.

Otra manifestación de esté cambio constante, de la relatividad de los datos que majamos, que nos aleja de otras ingenierías es la imposibilidad de utilizar métricas prescriptivas. Que el momento flector de una viga en voladizo supere cierto valor, sin duda dará como resultado que se rompa, pero, por poner un ejemplo, ¿cuál es el valor máximo de bugs abiertos que puede tener un proyecto antes de que la calidad percibida sea mala?. Es muy difícil gestionar los proyectos de software de manera puramente analítica pues la certidumbre es poca y la posibilidad de sesgar las métricas es amplia.

No existen actividades repetibles

Barco en construcción Cada línea de código, unidad cuántica de los proyectos de software, es única y solo es relevante en un contexto determinado. La industrialización se basa en la especialización y la repetibilidad. Todos los tornillos de rosca métrica son idénticos. Sin embargo no hay valor en construir dos piezas de software que sean idénticas.

Durante el desarrollo de un proyecto industrial o de construcción existen numerosísimas actividades que se repiten de manera idéntica. Incluso vasta con repetir elementos constructivos ensamblándolos para logra más funcionalidad. Basta añadir secciones para lograr un barco con más capacidad o basta con añadir más módulos para lograr una Terminal 4 de Barajas. Esto no ocurre en el software, cada módulo es radicalmente diferente del anterior al menos en algún aspecto. Por eso la especialización de los ‘operarios informáticos’ es, en cierto modo, contraproducente.

Además los desarrolladores se ven a si mismos más como artesanos que como operarios cuando describen su actividad profesional, por algo será.

La fuerza productiva no es fácilmente reemplazable

Y el desarrollo de software exige personal altamente capacitado. No existen dos desarrolladores con las mismas capacidades. Es relativamente fácil entrenar a un nuevo operario de planta es relativamente fácil sustituirlo por otro y la productividad no se verá mermada. Se puede tratar a los operarios de una planta como una máquina más (no digo que esto sea correcto, digo que es posible). Evidentemente las máquinas son fácilmente reemplazables al menos sobre el papel.

Todos los que hemos gestionado proyectos coincidimos que sea cual sea el proceso de desarrollo que seguimos el que un desarrollador cause baja siempre es un problema. Sabemos que nunca encontraremos otro con los mismos conocimiento y destrezas y con el conocimiento sobre el proyecto que el anterior atesoraba. Este es un tema que ya he tratado en anteriores ocasiones y por tanto no me extiendo más.

El software puede proporcionar valor incluso cuando no está completado

Puente en construcción Medio coche, medio barco, medio edificio o medio puente no sirven de nada. No son utilizables, no suponen un retorno de la inversión y además no se puede recibir feedback ninguno sobre el retorno de la inversión recibido frente al esperado y como mejorar este ratio.

La mitad de un proyecto de software, considerada como el momento en que la mitad de los requisitos están implementados, si se ha considerado el retorno de la inversión como principal parámetro a la hora de priorizarlos, aportará típicamente más de la mitad del retorno de la inversión esperado. Además es posible poner en producción la mitad de un software. No estará completo, cierto, pero no ayudará en múltiples aspectos. Dicho de otra manera Open Office es rival de Microsoft Office por un motivo claro, no necesitamos absolutamente toda la funcionalidad para que un software aporte valor. Además esta característica del software hace que sea mucho más fácil obtener feedback e incorporarlo al proyecto.

Existe un consenso claro entorno que a que una aproximación iterativa es la mejor manera de desarrollar proyectos de software. Sin embargo la aproximación en los proyectos industriales o de construcción rara vez es iterativa más haya de la fase de prototipado.

La motivación de los desarrolladores es lo que más influye en la productividad

Aunque existen muchos estudios y experiencias que hablan de que la implicación de los operarios de cadenas de montaje en el proceso productivo de principio a fin a logrado grandes mejoras de productividad, es cierto que el impacto de la motivación de los operarios industriales sobre el resultado final y la productividad es limitado.

Sin embargo, numerosísimos autores sobre gestión de proyectos informáticos han resaltado la motivación y la capacidad de trabajar como un equipo con el factor más determinante sobre los resultados de un proyecto. El primer autor en hablar y describir este fenómeno fue Boehm en 1981 y desde entonces son incontables los gestores de proyectos y las metodologías que lo han ignorado.

Dicho lo anterior, creo que es hora de olvidarse de tratar de llevar las técnicas de otras ingenierías y empezar a asumir que la nuestra es diferente y que debe encontrar su propio camino. Ya hay grandes nombres que está andando ese camino.

Panel de proyecto para Scrum for Team System

Muchos de los clientes con los que colaboro en implantaciones de Scrum, además de Team System, utilizan el tracional panel de proyecto de Scrum para hacer el seguimiento del proyecto. Dicen que lo encuentran más visual y sin duda lo es. Pues bien gracias a uno de estos clientes he conocido una herramienta gratuita y de código abierto que podemos encontrar en CodePlex, que desde los datos de un proyecto de Team System que use la plantilla metodológica de Cochango en su versión 2, es capaz de generar automaticamente el tradicional panel de proyecto Scrum. Podéis verlo en la imagen siguiente.

Panel de proyecto Scrum 

Sin duda esta útil herramienta nos ahorrará el trabajo de tener que mantener el panel a mano. Podéis descargala desde su sítio en CodePlex.

¿Pero dónde $%&Qñ&$ se ha producido la excepción?

Existe un truco bastante simple y útil que nos permite saber en que momento exacto se está producciendo una excepción. Me sorprende que sea desconocido por un motón de desarrolladores con los que me cruzo.

Se trata de usar la capacidad del depurador de Visual Studio para que el depurador para la ejecución cuando se produce una excepción de un tipo o tipos determinados (o de cualquier tipo si así lo queremos).

Para ello basta con utilizar el dialogo Exceptions (Excepciones) al que se puede acceder mediante la combinación de teclas Crtl + Alt + E.

Exceptions Dialog

Este cuadro de dialogo nos permite seleccionar que excepciones queremos que paren la ejecución de nuestro programa (lógimente si se ejecuta bajo el depurador) cuando se producen. El comportamiento por defecto es que el depurador solo salte cuando se detecta que la excepción no ha sido manejada, no el momento en que la excepción se ha producido.

En el cuadro de diálogo por defecto aparecen las excepciones de .Net Framework y de C++ habituales, pero podemos añadir nuestros propios tipos de excepciones como podéis ver en el siguiente diálogo que aparece pulsando en el botón Add… (Añadir…)

Add custom exception type

Espero que os sea útil ese pequeño truquito.