lunes, 9 de noviembre de 2015

NullReferenceException en método AjaxRequestProcessor.Run() con AjaxPro 5.7.22.2

Antecedentes


Alguien se le ocurrió una vez, que la mejor forma de conectarse de forma asíncronica desde Javascript (no existía jQuery como ahora) al servidor Web era usando AjaxPro (Ajax.dll). Bueno, eso funcionó, pero trajo un problema arrastrado por años, ahora que me dijeron "resuélvelo de una vea papá". Bueno, el error lo logré resolver luego de semanas cabezeandome. El mensaje en el Visor de Eventos decía en resumen:

NullReferenceException en Ajax.AjaxRequestProcessor.Run()

Antecedentes productivos:

  • Se usaron dos tipos de servidores, web primero Windows Server 2003 32 bit y luego Windows Server 2008 64 bit.
  • El ambiente productivo usa Framework 2.0 y Visual Basic .NET.
  • La arquitectura es un balanceador con 4 servidores Web y un servidor de base de datos.
  • Son 4 aplicaciones Web, las 4 usan 4 AppPool, 3 AppPool tienen 3 worker process y uno tiene 7. Todos tienen diferente tiempo de reciclaje.
  • El ambiente tiene mediana carga 2000 RPM (Request por Minuto) según la fabulosa herramienta Newrelic.
  • Las 4 aplicaciones usan Ajax.dll 5.7.22.2 liberada por el año 2005.

Antecedentes del error:

  • El error da irregularmente, sin un horario dado.
  • El problema puede dejar de dar durante días.
  • El error no daba en ambiente de desarrollo (lo típico).

El error registrado en el visor de Eventos es:

Event code: 3005 
Event message: An unhandled exception has occurred. 
Event time: 10/18/2015 3:12:47 PM 
Event time (UTC): 10/18/2015 6:12:47 PM 
Event ID: 305bbfa9f184433986b6655786e66f72 
Event sequence: 50 
Event occurrence: 1 
Event detail code: 0 
 
Application information: 
    Application domain: /LM/W3SVC/416041936/Root/SitioTest-1-130896653636875000 
    Trust level: Full 
    Application Virtual Path: /SitioTest 
    Application Path: C:\Inetpub\wwwroot\Test\Sitio\1.0\SitioTest\ 
    Machine name: Servidor-1 
 
Process information: 
    Process ID: 6948 
    Process name: w3wp.exe 
    Account name: NT AUTHORITY\NETWORK SERVICE 
 
Exception information: 
    Exception type: NullReferenceException 
    Exception message: Object reference not set to an instance of an object. 
 
Request information: 
    Request URL: http://sitio.cl/folder/ajax/SitioWebDotNet.namespace_clase,App_Web_datos.aspx.fe7917e2.ashx 
    Request path: /sitio/ajax/SitioWebDotNet.sitio_namespace_sitio,App_Web_datos.aspx.fe7917e2.ashx 
    User host address: X.X.X.X 
    User:  
    Is authenticated: False 
    Authentication Type:  
    Thread account name: NT AUTHORITY\NETWORK SERVICE 
 
Thread information: 
    Thread ID: 1 
    Thread account name: NT AUTHORITY\NETWORK SERVICE 
    Is impersonating: True 
    Stack trace:    at Ajax.AjaxRequestProcessor.Run()
   at Ajax.AjaxHandler.ProcessRequest(HttpContext context)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
 
 
Custom event details: 

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

Si uno miraba el contenido del ashx indicado en el error: http://sitio.cl/folder/ajax/SitioWebDotNet.namespace_clase,App_Web_datos.aspx.fe7917e2.ashx, no había nada raro.

Lo que intenté, sin que funcionara

  • Cambiar la DLL 5.7.22.2 a la última versión 9.2.17.1. No fue posible por que la versión que uso no usa JSON y la nueva usa JSON, cambiar todo el código, validar las entradas y salidas era mucho trabajo, quizá de meses.
  • Dejar sólo un servidor, sacándolo del balanceador de carga.
  • Revisar el código fuente: JS, código VB.Net, no encontré errores.
  • Dejar todos los Pool con 3 WP y el mismo tiempo de reciclaje.
  • Evalué pasar de AjaxPro a Ajax 1.0 de Microsoft, pero la cantidad de código era inmensa.
  • El error no da cuando se recicla un pool, era una teoría que tenía
  • Revisé los LOGS de IIS de los 4 servidores y no había algún de patrón del error, que fallara en todos a una hora, o que luego de un reciclaje de los pool fallara.

Solución


La solución fue para cada uno de los 4 Pool de las aplicaciones bajar todos los Worker Process a 1. De pasada dejarles el mismo tiempo de reciclaje. Me acordé que en el blog de Google se hablaba que tenía problemas en balanceo, y quizá pensé el error se da en Web Farm y Web Garden. Y era eso, ¡toque y fama!. Luego de monitorear los errores del visor de eventos durante 2 semanas observé que el problema desapareció. Recomiendo usar para visualizar de mejor forma los Event Logs la herramienta Event Log Explorer, que tiene una licencia Free.

Referencias



Bueno, espero que les sirva de ayuda, en caso que tengan este engorroso error.