EF 6: Connection resiliency y azure

Seguro que de muchos es sabido que cuando trabajamos con Sql Database es posible que alguna de nuestras operaciones pueda fallar, independientemente de si usamos EF, NH o directamente con nuestro SqlClient, debido a inestabilidades de la red o problemas de back-end [si desea explorar el porque de la realidad de estos problemas le recomiendo este enlace].  Aunque en la realidad esto no es algo ni mucho menos habitual, puede pasar, y, por lo general, sino somos conscientes de ello suele dar bastantes dolores de cabeza, por lo aleatorio de los fallos. Por supuesto, hay muchos workaround para este problema, y como no, también para los que usamos actualmente EF, en cualquier de sus versiones como por ejemplo este que comenta mi buen amigo Cesar de La Torre. en un post de hace una eternidad. Con el fin de hacer  esto más sencillo para nosotros y en realidad para resolver otros posibles problema similares para este u otros motores relacionales el equipo de EF ya tiene en la rama de EF 6 nuevas funcionalidades.

Estas nuevas características se pueden concretar en los siguientes elementos:

IExecutionStrategy

Esta interfaz define el contrato para la pieza que tendrá como responsabilidad la ejecución de operaciones que potencialmente necesiten reintentarse, por ejemplo las operaciones sobre Sql Database. El contrato de esta interfaz no es nada complicado como podemos ver a continuación:

 

 

La idea básica que hay detrás de esta interfaz es poder envolver una acción en un determinado ámbito capaz de decidir si las excepciones que se produzcan son o no candidatas para reintentarse, por ejemplo porque entendemos que es un fallo de Sql Database y no relacionado con el mapeo, consulta etc…, cada cierto tiempo. Por supuesto, decidir si una excepción  de una operación implica que la operación debe repetirse es algo configurable y no fijo, cuya implementación esta marcada por una nueva interfaz, que vemos a continuación.

 

IRetriableExceptionDetector

Mediante este contrato tendremos la posibilidad de especificar que excepciones son candidatas a “resolver” por medio de reintentos, el siguiente código representa este contrato

 

 

IRetryDelayStrategy

Este es el último elemento que necesitamos, y probablemente el más sencillo puesto que tiene como única finalidad marcar el tiempo entre reintentos de operaciones fallidas.

 

 

 

Bien, ahora que ya conocemos las piezas, ya podemos entender que tenemos para Sql Database, y esto, no es más que implementaciones concretas para estos contratos que podemos “inyectar” dentro de EF .

La implementación para el trabajo de Azure, Sql Database, se basa principalmente en la clase SqlAzureExecutionStrategy, que tendremos por defecto en el proveedor de Sql Server por defecto.

Como observará, en realidad esto no tiene nada más que el marcador de tiempos, ExponentialRetryDelayStrategy, que cuyo nombre indica hace un incremento exponencial basado en la siguiente fórmula:min (minDelay + coefficient * random(1, maxRandomFactor) * (exponentialBase ^ retryCount – 1), maxDelay), y un detector de excepciones personalizado que permitirá reintentar las siguientes excepciones.

 

  • SqlException con diferentes numberos de error, revisar el código siguiente para ver los casos concretos.
  • Un TimeoutException.

 

 

Como se establece la estrategia que queremos usar? por ejemplo esta para Sql Database?, pues bien, tan simple como hacemos otras inyecciones, por medio de nuestro DbConfiguration y el método AddExecutionStrategy.

Si nos fijamos un poco veremos como lo primero que hace este método es recuperar el proveedor para el que aplica esta estrategia, buscando un atributo, DbProviderName. Una vez localizado este atributo se establece el dependency resolver con la estrategia indicada. A partir de ese momento, ya tendremos disponible nuestra estrategia de reintentos..

 

 

Bueno, esto ha sido todo, espero que os sigan gustando las novedades de EF 6 y que sigáis viendo todo lo nuevo que poco a poco vamos teniendo

Unai

Deja un comentario

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