[ASP.NET] Acelera tus WebSites con WebCache
Hola que tal, si bien no es nada nuevo esto de WebCache, he visto que es poco utilizado y realmente muy útil, pongámonos en la siguiente situación :
“Tienes una consulta a una fuente de datos, la cual tiene un tiempo de ejecución y/o de CPU considerable, los datos tienen una frecuencia de actualización de unos 30 minutos, por ejemplo un reporte del estado sobre algún proceso.”
Ahora bien, podríamos pensar en usar sesiones , con todo el costo en rendimiento y problemas de escalabilidad, pero ya que las sesiones son por usuario, cuando otro usuario, alguien que no ha ingresado a ver el reporte, lo haga, de todos modos deberá esperar, sin considerar que luego de 20min (tiempo de vida por defecto de las sesiones), el usuario que ya había ingresado, va a tener que esperar nuevamente. Entonces las sesiones no son una solución efectiva al problema.
Desde la versión 1.1 de ASP.NET (hace ya bastantes años, aunque se recomienda usarlo desde la versión 2) se implemente la Clase Cache, que nos permite persistir en memoria objetos, además nos permite definir la cantidad de tiempo que los datos van a persistir e implementar un callback para cuando la cache expira. Esta cache es compartida por todas las solicitudes al sitio, no solo por usuario.
Un pequeño extracto de código de una aplicación(modificado):
Private Sub getReporte()
Dim dt As New DataTable
If Cache.Item("datos") Is Nothing Then
dt.ReadXml(Server.MapPath("Ventas2.xml"))
Cache.Insert("datos", dt, Nothing, DateTime.Now.AddMinutes(30),
TimeSpan.Zero, CacheItemPriority.Default, New CacheItemRemovedCallback
(AddressOf ReportRemovedCallback))
Else
dt = DirectCast(Cache.Item("datos"), DataTable)
End If
End Sub
Esta pequeña función obtiene los datos de un XML que es bastante extenso,(en realidad el código original hace referencia a un WebService que se demora bastante en responder, cerca que 20 segundos). Pero veamos en detalle:
-
Primero que nada revisamos si los datos están en cache, con Cache.Item(key)
-
Luego, en el caso que no estén en la cache, los vamos a buscar leyendo del xml normalmente, luego se insertan el cache con Cache.Insert y le damos un tiempo de vida a esta entrada en el cache de 30 minutos (AddMinutes(30)), también seteamos mediante un objeto CacheItemRemovedCallback la dirección del método (ReportRemovedCallback), esta es la función que se va a ejecutar cuando el cache expire.
-
En el caso que ya tengamos los datos en el cache (según el paso 1), simplemente hacemos el casting para pasarlos a un datatable.
Ahora si vemos la función ReportRemoveCallback tenemos que llamamos nuevamente a la lectura del Reporte, generando nuevamente la llamada. Se lo que estás pensando, estoy se está generando todo el día independiente si se esta viendo realmente, bueno, esto lo puedes controlar programáticamente, es decir, programar para que el cache se vuelva a generar si estoy dentro de ciertas horas, todo depende de la frecuencia y horas en los que los usuarios consultas el reporte.
Public Sub ReportRemovedCallback(ByVal key As String, _
ByVal value As Object, ByVal removedReason _
As CacheItemRemovedReason)
getReporte()
End Sub
En la práctica el cache compartido y la validación de la existencia de los datos en el mismo, hace que la experiencia de usuario al momento de leer el reporte se mejore bastante. En mi caso, esto era una llamada a un Web Service, que fácil se demoraba 20 segundos, y era consultado desde un teléfono Blackberry, ahora es prácticamente instantáneo y solo con utilizar esta excelente clase.
Espero que te sirva, a mi , ufff, bastante, y a los usuarios, mucho más.
Saludos!
Gonzalo