@pierre-gilles je ne sais pas si c’est le cas, mais on dirait réellement que soit la base de données soit Gladys est en mode bloquant à ce moment là.
Car vraiment plus rien ne répond. Donc soit j’ai totalement tord (ce serait pas la première fois ), soit il y a quelque chose à faire pour optimiser un peu cette partie.
De mon côté, je vois un processus node index.js à 100% du CPU, quand l’écriture sur la carte SD de mon Raspberry Pi ne semble pas à 100% de I/O.
En fait lorsque vous enregistrez un appareil, Gladys va faire 2 choses:
Si certaines features sont en historique désactivés, Gladys va purger tous les états de ces features. Cela représente potentiellement des millions de lignes sur certaines DB, ce qui peut bloquer la DB pendant pas mal de temps lors de la suppression.
Après ça, Gladys lance un VACUUM, opération qui va « réellement » supprimer la data du disque, et libérer de l’espace. VACUUM est une opération bloquante, et pendant toute la durée du VACUUM, la DB, et donc Gladys, n’est pas accessible. Sur les petites DB, c’est invisible, sur les grosses DB, ça peut prendre 20 minutes et effectivement on a l’impression que c’est « cassé », alors que non ça travaille juste !
La solution que je vois :
Coder une tâche de suppression d’états « background » qui supprime en petit batch afin que Gladys ne soit pas bloquée lors de la suppression de features à millions d’états. Il faut faire des tests et trouver le bon chiffre pour que ce soit ni trop bloquant, ni trop lent.
Retirer le VACUUM immédiat et mettre en place une tâche de VACUUM nocturne programmée et activable/désactivable (toutes les semaines par exemple).
La contrepartie de tout ça, c’est que l’effet « libération de stockage » ne sera plus immédiat, suite à une purge d’états il faudra attendre la prochaine nuit ou attendre une semaine que Gladys se purge. Eventuellement, on peut mettre un bouton quelque part pour purger manuellement mais il faut que l’utilisateur soit conscient que Gladys sera indisponible pendant tout le temps de la purge.
Par contre j’ai une assez grosse semaine donc je pense pas pouvoir regarder dans les jours qui viennent, je regarderais soit en fin de semaine, soit dans le courant de la semaine prochaine ! Je vous tiens au courant
Mais 20 min pour une petite modif de nom par exemple c’est très long. C’est très bloquant voir assez agaçant en faite, même si on sait que Gladys n’est pas cassé et qu’elle travaille en fond.
Pour ma part je pense que le nettoyage peut attendre plus tard comme tu le proposes. Et activable/désactivable par l’utilisateur peut être bien.
Merci pour les détails, je comprends mieux pourquoi on a tous la sensation que c’est bloquant.
Je suis pour la solution du VACUUM la nuit (entre 2h et 4h du matin par exemple).
Quel utilisateur va réellement se soucier de la taille de sa DB à quelques heures près ?
Après faire un VACUUM la nuit, il faut réfléchir sur le moins pénalisant car, par exemple, je gère mon chauffage électrique et poêle a granulé avec Gladys et NodeRed, donc du coup toutes les nuits entre 2h et 4h mon chauffage serait bloqué dans sa position pendant 20 min?
Dans ce cas de figure j’aimerais plutôt avoir un mode manuel du VACUUM.
Autre exemple si tu ajoutes une fonction Alarme à Gladys, les cambrioleurs auront 20 min tranquille toutes les nuits.
@pierre-gilles ça ne devrait pas faire ça sur l’ajout d’une feature. Je viens de faire le test et comme les autres ça prend du temps ( 4 minutes sur de l’amd64 )
Je suis à 14GB de ram pour le conteneur, va falloir que je limite un peu l’utilisation
Pour information je travaille sur ce sujet aujourd’hui, j’ai bien avancé ce matin et j’ai créé une PR
Mon approche:
Désormais, lorsqu’on enregistre un device où plusieurs fonctionnalités ont a la case « Oui, conserver les états » décochée, je lance des jobs en background qui vont aller nettoyer les états passés, de manière un peu plus smart que ce qui était fait juste que là.
Le job va compter en DB combien il y a d’états / états aggrégés pour chaque feature, puis va nettoyer en petit batch de 1000 les états, afin d’éviter de surcharger la DB. Entre chaque batch, Gladys attend 100ms pour laisser de l’air à Gladys.
Pour cleaner 5 millions d’états, il faut donc 5 millions / 1000 = 5 000 batch.
5 000 * 0.1 = 500 secondes = 8,3 minutes à minima d’attentes entre les batch, si on rajoute 100ms par clean, ça fait 16 minutes pour cleaner 5 millions d’états en arrière plan, de façon non bloquante pour Gladys et en douceur
Côté Gladys, tout job en arrière plan peut-être suivi en direct dans l’onglet « Tâches en arrière plan »:
Concernant le VACUUM, j’ai choisi une approche « manuelle » pour l’instant, vu l’impact que ça a sur la disponibilité de Gladys sur les grosses DB.
J’ai retiré le VACUUM lors de l’enregistrement des devices, et j’ai rajouté un bouton manuel dans les paramètres systèmes avec un texte qui indique clairement que Gladys sera indisponible pendant un certain temps suite au VACUUM.
L’idée c’est déjà de voir le temps que le VACUUM prend sur différentes instances, et laisser le choix à l’utilisateur de le faire/ou non.
Ensuite, on pourra éventuellement rajouter un job de nuit mensuel par exemple, mais il faudra bien communiquer dessus et le rendre désactivable pour ceux qui veulent une disponibilité de Gladys maximale.