[WCF] InstanceContextMode.Single y variables globales

Los servicios WCF (esos grandes amiguitos), tiene varios modos de instanciación (PerCall, PerSession y Single), la documentación oficial la podéis encontrar aquí, pero quería hablaros del comportamiento del single.

En mi proyecto actual se decidió cambiar la forma de instanciación de los servicios a Single para ganar rendimiento, y en un principio viendo el coste del cambio, “unas dos líneas de código”(jajajajajaja), se decidió hacerlo. Yo en un principio era un poco escéptico porque conocía como estaba construida la “casa” y en fin… tenía mis dudillas, y la verdad se nos complicó un poco el cambio, os cuento…

 

Un poquillo de culturilla, cuándo se instancia un servicio en modo Single, se crea una única instancia si no existe y si ya existe no se crea nada (lo que viene siendo un Singleton), esto es genial, lo que pasa es que todas las llamadas que haga ese servicio a nuevas clases realmente van a tener una única referencia y no se van a estar creando nuevas clases una y otra vez, vamos que el “new class()” realmente no tiene por qué crear una nueva instancia, si no reutilizar una ya creada. Este comportamiento, totalmente lógico, puede dar algún problema porque no es del todo explícito.

Yo hasta aquí, no le veo más que ventajas, nuestro proyecto actual tenía un montón de problemas de rendimiento porque se generaban muchas llamadas a servicios (bueno esa era una de las muchísimas razones), así que nos pusimos manos a la obra y… zas en toda la boca. De buenas a primeras los servicios no conseguían levantarse, y los que lo conseguían en unas mínimas pruebas de carga empezaron a dar problemas de concurrencia y los que no los daban no funcionaban como tenían que funcionar.

 

Después de los primeros momentos de pánico y miradas asesinas hacia los pobrecillos que hicimos el cambio, nos pusimos a mirar detenidamente y vimos que en nuestras clases de lógica de negocio y acceso a datos se usaban muchas, muchísimas variables globales (no, no, no…chicos malos). El “problema” es que cuando se está trabajando en un servicio en modo Single, cualquiera de sus clases que estén dentro del contexto de la llamada del servicio estarán apuntando a una única referencia y también “están” en modo single, así que a todos los efectos

public class UnaDAL()
{
List<int> listaEnteros = new List<int>();
}

se convierte en algo similar a esto

public class UnaDAL()
{
static List<int> listaEnteros = new List<int>()
}

Pues claro si luego la utilizas sin locks y sin pensar en la concurrencia, esto no funciona.

 

Conclusiones

Todos a una… “Las variables globales son malas”, aunque las generalizaciones son malas, en general no se deberían utilizar salvo en casos realmente necesarios y controlados. Y por otra parte, creo que utilizar los servicios en modo single se tiene que hacer cuándo tú aplicación lo soporta o está medianamente bien diseñada. En nuestro caso actual, estamos trabajando en ello y parece que vemos la luz del túnel y la verdad es que ahora mismo nuestras clases tienen mucha mejor forma y salud… Aunque debo deciros que los primeros momentos de pánico fueron muy graciosos…

 

Un saludico y hasta la próxima.

5 comentarios en “[WCF] InstanceContextMode.Single y variables globales”

  1. En efecto es un problema muy comun cuando desarrollamos WCF con la instanciación en modo Single, porque como has comentado acertadamente todo se vuelve singelton, cuando se quiere utilizar este tipo hay que tener muy claro que los servicios estan totalmente desacoplados sino vas a tener que modificar mucho tu codigo.

    Buen articulo

  2. sr. Julio, un ejemplo con código de encolar las peticiones en multihebra para que cada tarea encolada se ejecute en su propio hilo ?? salu2&grazie

  3. Buen articulo Mario, lo único comentar que realmente el problema aqui no es WCF sino saber lidiar con la concurrencia.
    Uno de los problemas que nos vienen ahora a los desarrolladores es tener que trabajar con la concurrencia en nuestras aplicaciones, con eso no quiero decir que las variables globales sean malas, pero hay que tener en cuenta estas cositas…

    Saludos. Luis.

  4. Luis, totalmente de acuerdo que el problema es la concurrencia y no WCF, lo único es que al poner el servicio a single estás más obligado a pensar en ella, y quizás no todo el mundo lo tenga claro 🙂

    Pero realmente creo que no hay que abusar de las variables globales… para lo justico y poco más….

    Es bueno saber de tí… ohhhhh Master WWF 🙂
    Mario.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *