Réécriture de l'export JSON pour améliorer les performances
Détails
-
API : Refactorise les fonctions de récupération de champs -
API : Exporte les champs sous un nouveau format plat pour le JSON -
API : Importe les champs depuis le format JSON v2
Explications
L'export d'un gros rapport provoquait jusque là un timeout et ne se terminait pas à cause des récursions exponentielles que doit faire PostgreSQL. En réécrivant le format d'export pour n'avoir qu'un seul niveau de champs, j'ai pu exporter le gros rapport en moins d'une seconde (export 12Mo).
Note : L'export d'un gros rapport est maintenant utilisable mais l'import d'un gros rapport n'est pas encore bien fonctionnel et résulte en un Gateway Timeout avec un processus Python qui occupe tout. Je pense que si on fait un import, il faut s'assurer que le serveur ne fait aucune autre tâche pour qu'il ne soit pas interrompu. À terme il faudrait probablement déporter les gros calculs dans Celery.
Starting importing 82046 fields to 122781...
Au bout de 5 minutes d'exécution de l'import du gros rapport, le processus Python consomme 36% de CPU et 573Mo de RAM. Après 17 minutes, 63% de CPU et 630Mo de RAM. À raison d'environ 0.023s par champ à importer, le temps d'import d'un gros rapport de 82046 champs est d'environ 27 minutes. Temps d'import mesuré une fois complété : 30 minutes.
Note technique : Un commit de refactorisation a provoqué un bogue qui n'a pas été détecté par les tests unitaires mais rapidement vu en essai réel. La raison c'est que la refactorisation a donné un mauvais identifiant de vue SQL, mais dans les tests cette vue SQL existe bien car la vue est créée automatiquement lorsqu'on récupère le champ concerné, ce qui est fait dans les fixtures. Pour résumer, tels que sont prévus les tests, il y a un comportement additionnel par rapport à la réalité qui a faussé la détection de la régression et a priori je ne vois pas comment changer ça pour éviter. Tant pis.
Note optimisation : J'ai détecté que la requête de mise à jour de champ pouvait être très longue (parfois 8 secondes). Il s'agit de la partie autorisation qui fait cela. Le problème peut être contourné lorsqu'on utilise un lien de partage avec des accès restreints à certains rapports, voire même avec des champs filtrés. L'autorisation a besoin de scanner moins de champs pour vérifier si on a bien le droit de réaliser l'action. Pour l'instant c'est le plus pragmatique à faire.
Captures d'écran
Références
https://taches.cemea.org/b/bJJXFZxe6pRHN8uHy/dev-web/8Mg8jcsqatxYnmWxt