¿Por qué debo definir "debug=false" en web.config?, Parte II

Published Wednesday, May 23, 2007 5:53 AM

En la primera parte de este artículo revisamos parte del impacto de definir debug="true" en nuestro archivo de configuración web.config. Dentro de lo estudiado, abarcamos la revisión de la carpeta temporal de asp.net y cómo se generan los archivos de código de las páginas y controles, para finalizar con la generación de los ensamblados que resultan de la compilación.

En ésta oportunidad cubriremos cómo actúa asp.net para manejar las modificaciones de los archivos que ya están compilados. Excluiremos por motivos obvios las modificaciones a archivos de configuración, como de la carpeta bin o configuración de IIS.

Antes de entrar de lleno en la modificación, revisemos todas las opciones disponibles para la compilación en asp.net 1.1.

Opciones de compilación 

En la primera parte, utilizamos elemento de compilación del archivo web.config que es creado por defecto:

<compilation defaultLanguage="c#" debug="false"    />
 

Sin embargo, existe una cantidad importante de opciones disponibles para la compilación. Veamos uno más completo para VB.NET y C# respectivamente.

<compilation defaultLanguage="VB" debug="true"
numRecompilesBeforeAppRestart="?cantidad" explicit="true|false" strict="true|false"
batch="true|false" batchtimeout="?seconds" maxBatchGeneratedFileSize="?kilobytes
"
maxBatchSize ="?cantidad" tempDirectory="?ruta">
</
compilation>

<
compilation defaultLanguage="c#" debug="true"
numRecompilesBeforeAppRestart
="?cantidad"
batch="true|false" batchtimeout="?seconds"
maxBatchGeneratedFileSize="?kilobytes"
maxBatchSize="?cantidad" tempDirectory="?ruta">
</compilation>

 

El significado de las opciones es a veces intuitivo y otras no. Veamos una por una, excluyendo las dos primeras que ya conocemos:

  • numRecompilesBeforeAppRestart: Se refiere a la cantidad de re-compilaciones dinámicas que se realizan antes de que se produzca un reinicio de la aplicación. Es trascendental aclarar que como re-compilaciones se refiere a cambios en los archivos de páginas, controles y otros recursos, dentro de los cuales definitivamente NO se incluyen los archivos de configuración (web.config, machine.config, etc.), los ensamblados de la carpeta bin y modificaciones al directorio virtual o aplicación web. El valor por defecto es 15. Aunque la documentación no lo dice, sí funciona para aspnet 1.1 (ver más).

  • explicit y strict: Las mismas opciones disponibles para los desarrolladores VB. Para C# no tienen efecto.

  • batch: Si es verdadero, se compilan los archivos agrupados de la mejor forma posible (como hemos visto hasta ahora). En caso de ser falso, se compila un archivo por página o control. No confundir con debug=false. En este caso se compila realizando las optimizaciones apropiadas al código.
  • batchtimeout: tiempo en segundos que se dará para que alcance a compilarse un grupo de archivos. En caso de demorar más tiempo del especificado, para ese requerimiento se cambia la modalidad a por archivo.
  • maxBatchGeneratedFileSize:  Según la ayuda, especifica el tamaño máximo (en KB) de los archivos de código fuente generados en cada compilación por lotes (batch). Me surge la siguiente duda. Si el archivo de código generado de una página de mi sitio es más grande, ¿no lo va a compilar?
  • maxBatchSize: Cantidad de archivos que incluirá como máximo en cada ensamblado.
  • tempDirectory: Directorio donde se copiarán los archivos para la compilación.
Reutilización de ensamblados

Algo que no habíamos comentado antes y que es muy importante. El resultado de la compilación (ensamblados) no se ve afectado por reinicios de proceso, de servicio o de servidor. Cuando se procesa un requerimiento se revisa si el recurso (aspx, ascx) está compilado en el directorio temporal, y en caso de ser así, se utiliza el ensamblado sin consumir tiempo y recursos compilando nuevamente.

La siguiente imagen fue capturada de mi equipo el 10 de Mayo después de hacer un cambio a un archivo y podrán observar que se han mantenido los otros ensamblados con fecha 07 de Mayo.

Si notan con cuidado, verán un archivo que tiene como extensión DELETE. Pasemos a revisar como ocurre eso.

Modificaciones de archivos

Para no distorsionar cualquier prueba, he limpiado mi carpeta temporal por lo que ahora cuento con archivos generados el día de hoy (22 de Mayo). La siguiente imagen muestra el estado inicial de la carpeta temporal.

Para complementar lo anterior, se despliega ahora una imagen con las DLLs cargadas en memoria para el proceso aspnet_wp.exe (worker process de IIS 5.1 de Windows XP 32 bits). Para monitorear procesos, pueden utilizar las herramientas disponibles de SysInternals.

Después de realizar una modificación en el archivo WebForm1.aspx, y volver a ejecutarlo, hacer otra modificación y volver a ejecutarlo, se pueden observar los siguientes cambios en la carpeta temporal y en el proceso aspnet_wp.exe.

En la primera modificación se generó un ensamblado para almacenar el resultado de la compilación de este archivo modificado (wdjnsrvz.dll). Como luego se volvió a modificar el mismo, el primer compilado (wdjnsrvz.dll) ya no era necesario y se generó uno nuevo (5jbqtzyx.dll). El ensamblado que ya no se utiliza, se marca con la extensión .delete.

Adicionalmente, en el proceso aspnet_wp.exe se continúan cargando ensamblados a medida que se van requiriendo páginas. Recordemos que los ensamblados NO pueden ser descargados de un proceso, a menos que se descargue el dominio. Para el caso de una aplicación web, el dominio es la misma aplicación, lo que hará que no se descarguen los ensamblados hasta que la aplicación se recicle.

Limpiamos nuevamente nuestra carpeta temporal, definimos debug="true" y procedemos a modificar y forzar re-compilaciones.

Después de muchas modificaciones

Como era de esperarse, después de muchos cambios, la situación en el directorio temporal y el proceso no es de las mejores. Haz click en las imágenes para agrandar.

Una vez que modificamos los archivos más de las veces especificadas en numRecompilesBeforeAppRestart, el worker process (aspnet_wp.exe) se recicla, como era esperado.

Después del reciclado del proceso, este es el panorama en el directorio temporal y el proceso. Haz click en las imágenes para agrandar.

Con debug=”false”

Si repitiésemos todo los pasos anteriores, pero con debug="false", el resultado sería como el de la siguientes imágenes. Podrán ver que hay una menor cantidad de archivos, optimizados durante la compilación.


Si se revisan con detalle las imágenes anteriores, hay 4 ensamblados que no han sido modificados desde un poco más de 1 hora. Estos ensamblados son los que contienen los archivos Global.asax, WebUserControl2.ascx, WebUserControl1.ascx y WebForm5.aspx, que corresponden a los 4 archivos que no se han modificado en estas pruebas. Sólo se modificaron los WebFormN.aspx, con N desde 1 a 4.

A propósito, hemos comprobado que la opción numRecompilesBeforeAppRestart  sí funciona en asp.net 1.1.

¿Cuál es el valor adecuado para numRecompilesBeforeAppRestart?

Lamentablemente esta no es una pregunta sencilla de responder. En éste KB (http://support.microsoft.com/kb/319947/en-us) recomiendan definir un valor mayor la cantidad de archivos que actualmente se copian. Me imagino que hay algunos escenarios donde una recomendación de ese tipo hace sentido, pero en mi experiencia, la cantidad de archivos a subir a producción siempre es variable.

Otra implicancia de alto impacto

Existe una posibilidad de que una página pueda correr indefinidamente si  debug="true". De acuerdo al documento ASP.NET Performance Monitoring, and When to Alert Administrators, si está en true, el valor de <httpRuntime executionTimeout=/> y Server.ScriptTimeout serán ignorados, y dependerá del valor de <processModel responseDeadlockInterval=/> si se presenta la condición o no.

 

Espero en una tercera entrega, poder mostrar optimizaciones a nivel de código. Espero que ya estés medio convencido.

Desde Quito, Ecuador
Patrick

by pmackay
Filed under:

Comments

# Amigo mío Siempre estas Programando en .NET said on Wednesday, May 30, 2007 8:15 AM

En mi anterior artículo hice referencia al primer artículo de Patrick donde explicaba la importancia

# ASP.NET Espanol Blogs said on Wednesday, May 30, 2007 8:31 AM

En mi anterior artículo hice referencia al primer artículo de Patrick donde explicaba la importancia

# espinete said on Thursday, May 31, 2007 1:18 AM

Señor, cómo se puede acceder por código y saber si compilation debug es true o false ? Saludos.

# pmackay said on Thursday, May 31, 2007 1:02 PM

Espinete,

mira, no es muy elegante, pero funciona.

using System.Reflection;

bool b;

object o = System.Configuration.ConfigurationSettings.GetConfig("system.web/compilation");

b = (bool)o.GetType().InvokeMember("_debug", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, o, null);

b será verdadero o falso en dependiencia del valor de la configuración.

Saludos,

Patrick

# la visión de un ingeniero de campo said on Wednesday, July 11, 2007 11:47 PM

Como lo mencioné al terminar el segundo post sobre por qué no deho habilitar debug=true en web.config

# Carlos Walzer said on Friday, November 02, 2007 3:01 PM

Para confirmar lo que mi amigo Patrick MacKay explica en estos 3 artículos: ¿Por qué debo definir &quot;debug

# SergioTarrillo's RichWeblog said on Thursday, February 21, 2008 12:28 PM

De ahora en adelante [PLEFDS = para leer el fin de semana]. Digamos que hay dos maneras de tener el c&#243;digo

# .net y algo mas said on Sunday, March 23, 2008 2:59 PM

Todo acerca de Inline, beside, behind, Web Site Project y Web Application Project. De ahora en adelante

Leave a Comment

(required) 
(required) 
(optional)
(required)