Découvrez comment intégrer des fichiers Excel dans SEI ou une base de données SQL, en utilisant la technologie ODBC...
Optimisation des Imports en Batch Multithread dans Sage X3 pour Gagner en Performance
Optimisation des Imports en Batch Multithread dans Sage X3 pour Gagner en Performance
Dans les installations de Sage X3, les lenteurs d’import en standard deviennent de plus en plus visibles, surtout dans des environnements où plusieurs verticaux cohabitent. Ce phénomène est exacerbé par le fait que Sage, en tant qu'éditeur, ne contrôle pas toujours la qualité et l'intégrité des développements fournis pour chaque vertical, ce qui peut causer des conflits et des ralentissements. L'absence de vérification entre les différents développements intégrés dans le catalogue conduit souvent à des problématiques de performance.
Pour résoudre ce problème, il est possible de paralléliser les imports via un serveur batch, permettant ainsi d'exécuter plusieurs tâches simultanément et de contourner la nature monotâche des importations standard. Voici une explication de la solution et le code permettant cette optimisation.
Scénario classique
Prenons un exemple typique : l'importation d'une seule pièce prend environ 2 secondes. Dans une situation monotâche, importer 100 pièces prendrait donc 200 secondes. Cependant, en parallélisant l'import via 4 tâches distinctes, nous pouvons diviser ce temps par quatre, le ramenant à 50 secondes.
La seule contrainte à prendre en compte est le délai de scrutation du serveur batch, fixé par défaut à 30 secondes. Cela peut induire un léger décalage dans l'exécution mais reste largement compensé par le gain global apporté par la parallélisation.
Exemple de code pour la parallélisation d'import dans Sage X3
Voici le code permettant de paralléliser les imports en utilisant des tâches batch multithread dans 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)
# Query header
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
# Query Parameters
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 max
Elsif YIABL = 3
[F:YABL]PARAM="NOMIMP"
[F:YABL]VALEUR=mid$(filpath("tmp",[L]YFILELIST(YTHXTRXID],"csv"),31,30) # ABATRQTL.VALEUR = 30 Alpha max
Elsif YIABL = 4
[F:YABL]PARAM="NOMIMP"
[F:YABL]VALEUR=right$(filpath("tmp",[L]YFILELIST(YTHXTRXID],"csv"),61) # ABATRQTL.VALEUR = 30 Alpha max
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 max
Elsif YIABL = 7
[F:YABL]PARAM="VOLFIL"
[F:YABL]VALEUR=right$("[TMP]/"+[L]YFILELIST(YTHXTRXID]+".csv",31) # ABATRQTL.VALEUR = 30 Alpha max
Endif
Write [F:YABL]
Next YIABL
Write [F:YABR]
Next YTHXTRXID
If !fstat : Commit : Else : Rollback : Endif
# We loop on the queries until they finished to been executed
# Otherwise VAT will not be available
If find(YAOETPL,"YTRXSIHVAT","YTRXSIHCST")
Repeat
Read [F:YABR]NUMREQ = YNUMREQ(YX3BATCHOK)
# 1 = Standby (max 30s)
# 2 = In progress
# 3 = Finished
# 7 = Error
If [F:YABR]FLAG>2 : YX3BATCHOK += 1
Else : Sleep 1 : YX3BATCHSLEEP += 1 : Endif
Until YX3BATCHOK = [L]YTHDTRX
Endif
End YX3BATCHSLEEP
Explication de la solution
Le code ci-dessus illustre comment configurer des requêtes batch pour gérer plusieurs fichiers d'import en parallèle. Chaque fichier est traité dans une tâche distincte, identifiée par un NUMREQ unique. Les paramètres associés à chaque requête sont spécifiés dans la table ABATRQTL.
Le script boucle ensuite jusqu'à ce que toutes les tâches aient terminé leur exécution (avec des statuts possibles de "En attente", "En cours", "Terminé", ou "Erreur"). Cette boucle assure que les données nécessaires, comme la TVA, sont bien disponibles avant la validation de l'import.
Conclusion
Grâce à cette technique de parallélisation des imports dans Sage X3, il est possible de diviser par quatre (voire plus) le temps d'exécution global des imports, rendant ainsi le processus beaucoup plus efficace dans des environnements où plusieurs verticals cohabitent. Le principal avantage est une réduction considérable des temps de traitement, tout en maintenant une architecture standard sur le serveur batch.
Leave a comment