Blog navigation

Últimas entradas del blog

Optimización de las Importaciones en Sage X3 con Multihilo en Lote

 

Optimización de las Importaciones en Lote Multihilo en Sage X3 para Mejorar el Rendimiento

En las instalaciones de Sage X3, las ralentizaciones en las importaciones estándar se hacen cada vez más visibles, especialmente en entornos donde coexisten múltiples verticales. Este fenómeno se ve agravado por el hecho de que Sage, como proveedor, no siempre controla la calidad y la integridad de los desarrollos de cada vertical, lo que puede causar conflictos y ralentizaciones. La falta de verificación entre los diferentes desarrollos incluidos en el catálogo a menudo conduce a problemas de rendimiento.

Para resolver este problema, es posible paralelizar las importaciones a través de un servidor batch, permitiendo la ejecución de varias tareas simultáneamente y evitando así la naturaleza monotarea de las importaciones estándar. A continuación, se explica la solución y se proporciona el código que permite esta optimización.

Escenario clásico

Tomemos un ejemplo típico: la importación de una sola pieza tarda aproximadamente 2 segundos. En una situación monotarea, importar 100 piezas tomaría 200 segundos. Sin embargo, al paralelizar la importación mediante 4 tareas distintas, podemos dividir ese tiempo por cuatro, reduciéndolo a 50 segundos.

La única limitación a tener en cuenta es el tiempo de exploración del servidor batch, que por defecto es de 30 segundos. Esto puede causar un pequeño retraso en la ejecución, pero queda ampliamente compensado por la ganancia global proporcionada por la paralelización.

Ejemplo de código para la paralelización de importaciones en Sage X3

Aquí está el código que permite paralelizar las importaciones utilizando tareas batch multihilo en Sage X3:


Funprog   YTRX_IMP_X3_BATCH(YTHDTRX, YFILELIST, YAOETPL)
  Value Integer     YTHDTRX
  Value Char        YFILELIST()()
  Value Char        YAOETPL()

  Local File ="X3.ABATRQT"      [F:YABR]
  Local File ="X3.ABATRQTL"     [F:YABL]
  Local Integer YX3BATCHOK    : Raz YX3BATCHOK
  Local Integer YX3BATCHSLEEP : Raz YX3BATCHSLEEP
  Local Integer YTHXTRXID
  Local Integer YNUMREQ(YTHDTRX)
  Local Integer YIBAL

  Trbegin [F:YABR], [F:YABL]
  For YTHXTRXID=0 To (YTHDTRX-1)
    # Encabezado de consulta
    YNUMREQ(YTHXTRXID) = uniqid([F:YABR]) # max(ABATRQT.NUMREQ)+1
    [F:YABR]NUMREQ=YNUMREQ(YTHXTRXID)
    [F:YABR]DAT=date$
    [F:YABR]DFIN=date$
    [F:YABR]DOSSIER=nomap
    [F:YABR]FLAG=1
    [F:YABR]HEURE=format$("D:hhmm", date$)
    [F:YABR]MESSAGE=1
    [F:YABR]MONO=1
    [F:YABR]TACHE="IMPORT"
    [F:YABR]USER=[V]GUSER
    [F:YABR]CREUSR=[V]GUSER
    [F:YABR]UPDUSR=[V]GUSER
    [F:YABR]CREDATTIM=datetime$
    [F:YABR]UPDDATTIM=datetime$
    [F:YABR]LAN=[V]GLANGUE
    # Parámetros de consulta
    For YIABL=1 To 7
      [F:YABL]NUMREQ=YNUMREQ(YTHXTRXID)
      [F:YABL]NUM=YIABL
      [F:YABL]CREUSR=[V]GUSER
      [F:YABL]UPDUSR=[V]GUSER
      [F:YABL]CREDATTIM=datetime$
      [F:YABL]UPDDATTIM=datetime$
      If YIABL = 1
        [F:YABL]PARAM="MODIMP"
        [F:YABL]VALEUR=YAOETPL
      Elsif YIABL = 2
        [F:YABL]PARAM="NOMIMP"
        [F:YABL]VALEUR=left$(filpath("tmp",[L]YFILELIST(YTHXTRXID),"csv"),30)   # ABATRQTL.VALEUR = 30 Alpha máx.
      Elsif YIABL = 3
        [F:YABL]PARAM="NOMIMP"
        [F:YABL]VALEUR=mid$(filpath("tmp",[L]YFILELIST(YTHXTRXID],"csv"),31,30) # ABATRQTL.VALEUR = 30 Alpha máx.
      Elsif YIABL = 4
        [F:YABL]PARAM="NOMIMP"
        [F:YABL]VALEUR=right$(filpath("tmp",[L]YFILELIST(YTHXTRXID],"csv"),61)  # ABATRQTL.VALEUR = 30 Alpha máx.
      Elsif YIABL = 5
        [F:YABL]PARAM="TYPEXP"
        [F:YABL]VALEUR="2"
      Elsif YIABL = 6
        [F:YABL]PARAM="VOLFIL"
        [F:YABL]VALEUR=left$("[TMP]/"+[L]YFILELIST(YTHXTRXID]+".csv",30)        # ABATRQTL.VALEUR = 30 Alpha máx.
      Elsif YIABL = 7
        [F:YABL]PARAM="VOLFIL"
        [F:YABL]VALEUR=right$("[TMP]/"+[L]YFILELIST(YTHXTRXID]+".csv",31)       # ABATRQTL.VALEUR = 30 Alpha máx.
      Endif
      Write [F:YABL]
    Next YIABL
    Write [F:YABR]
  Next YTHXTRXID
  If !fstat : Commit : Else : Rollback : Endif

  # Iteramos en las consultas hasta que hayan sido ejecutadas
  # De lo contrario, el IVA no estará disponible
  If find(YAOETPL,"YTRXSIHVAT","YTRXSIHCST")
    Repeat
      Read [F:YABR]NUMREQ = YNUMREQ(YX3BATCHOK)
      # 1 = En espera (máx. 30s)
      # 2 = En progreso
      # 3 = Terminado
      # 7 = Error
      If [F:YABR]FLAG>2 : YX3BATCHOK += 1
      Else : Sleep 1 : YX3BATCHSLEEP += 1 : Endif
    Until YX3BATCHOK = [L]YTHDTRX
  Endif
End YX3BATCHSLEEP

Explicación de la solución

El código anterior ilustra cómo configurar consultas batch para manejar múltiples archivos de importación en paralelo. Cada archivo se procesa en una tarea distinta, identificada por un NUMREQ único. Los parámetros asociados a cada consulta se especifican en la tabla ABATRQTL.

El script luego itera hasta que todas las tareas hayan terminado su ejecución (con posibles estados de "En espera", "En progreso", "Terminado" o "Error"). Este bucle garantiza que los datos necesarios, como el IVA, estén disponibles antes de la validación de la importación.

Conclusión

Gracias a esta técnica de paralelización de importaciones en Sage X3, es posible dividir por cuatro (o más) el tiempo total de ejecución de las importaciones, lo que hace que el proceso sea mucho más eficiente en entornos donde coexisten varios verticales. La principal ventaja es una reducción considerable en los tiempos de procesamiento, manteniendo una arquitectura estándar en el servidor batch.

 
Publicado en: Sage X3, 4GL