Procesando archivos grandes en BTS 2006

Participe en un caso donde tuvimos que probar la nueva característica de BTS 2006 para transformar archivos sin ocasionar un System.OutOfMemoryException (OOM) si es que el tamaño del archivo al momento de estar formando el XML excede la cantidad de memoria disponible en la máquina. Por decirles un ejemplo de un archivo plano de 27 MB puede llegar a generar un archivo de salida de 110MB, pero el proceso de XML DOM puede a llegar a consumir más 1 GB en RAM.

Aunque la memoria RAM es mas barata en estos días, sigue siendo un recurso bastante limitado, si lo comparamos con un disco duro. En este aspecto, la nueva característica que ofrece BTS 2006 es hacer uso de disco duro para cargar el XML DOM del archivo para el proceso de transformaciones. Esto se hace por medio de la bandera TransformThreshold que se tiene que ubicar en HKLM\Software\Microsoft\BizTalk Server\3.0\Administration. La bandera no existe al momento de instalar y tiene un valor por default = 1048576 (1MB) y como se darán cuenta, el valor esta en bytes. Este valor indica que cualquier archivo mayor a 1MB que pase por el proceso de transformación empleará el proceso de swapping a disco duro.

En el caso que participe, inclusive empleando esta nueva característica seguí obteniendo la excepción OOM, por lo que tuve que escalar el caso con el grupo de producto obteniendo resultados un tanto importantes, además que si logre procesar el archivo de 27MB y lo hice en 5 mins con un TransformThreshold = 2MB

Tuve que hacer una optimización del archivo XSLT (can ayuda), ya que los ancestors son un killer dentro del proceso de transformación y debido a que el mapper genera XSLT con ancestors, se necesitan hacer algunos pasos adicionales, pero sencillos, para poder obtener un buen resultado. Lo malo es que no tengo todavía el detalle de cuando hacer este proceso de optimización al XSLT, pero pienso que tiene que ver con los archivos que sobrepasen el umbral establecido.

Proceso de optimización (gracias a Jay Lee):

  1. Validar Mapa en VS.NET

  2. En la ventana del output, verán el link hacia el XSLT que se genera. El archivo btm en realidad no contiene el XSLT.

  3. Salvar el XSLT a un archivo (de preferencia en el mismo directorio de la solución por control mas que nada)

  4. Optimizar el XSLT. Reemplezar todos los ancestors por "../", esto es buscar todas las cadenas "ancestor::*[1]/", "ancestor::*[2]/", etc. y reemplazarlas por "../", "../../", etc. El número dentro de los corchetes indica el número de nodos que hay que navegar hacia arriba, ejemplo:

    <xsl:if test="string($var:v38)='true'">
            <xsl:variable name="var:v39" select="ancestor::*[2] /HDR01/@PONum" />
            <xsl:attribute name="PONum">
            <xsl:value-of select="$var:v39" />
            </xsl:attribute>
    </xsl:if>

    Cambiarlo por

    <xsl:if test="string($var:v38)='true'">
            <xsl:variable name="var:v39" select=" ../../ HDR01/@PONum" />
            <xsl:attribute name="PONum">
            <xsl:value-of select="$var:v39" />
            </xsl:attribute>
    </xsl:if>

  5. Crear un mapa con el mismo esquema fuente y destino y dando clic en el gris verlas propiedades. Establecer la propiedad Custom XSLT Path = al path del XSLT optimizado que se acaba de crear.

  6. Probar el mapa con el archivo que esta ocasionando problemas.

El asunto con este proceso es que ya no se puede mantener el mapa usando el mapper, pero podría ser que la optimización la dejen al último. Aunque existe la oportunidad de hacer la optimización del XSLT en el mapper al momento de analizar todas las funciones de conversión que se están haciendo y ver cuales están generando ancestors. Una vez identificadas estas funciones, se pueden reemplazar por templates dentro de un Scripting Functoid del tipo InlineXSLT Call template (ver antes, ver después).

Como verán, esta optimización de los ancestors es muy sencilla, pero obviamente es algo que esperamos se resuelva pronto como decimos out-of-the-box. Se va a generar un KB y/o incluir como parte de la documentación.