Platform Auto-Upgrade & Module Auto-Import in multi-node cluster

When deployed in multi-node mode, one of the nodes should lock the database to pass the patches and import the modules from the importspec.

Bonjour Simon,

n’est-ce pas ce que garanti la feature de lock / auto-upgrade ? (cf. message “Autoupgrade lock” dans les logs système lors du démarrage).

Si ce n’est pas le cas, alors oui, je vote pour cette feature request…

En fait le lock est bien prévu depuis le début (d’où les traces) mais n’a pas encore été implémenté car ça pose plusieurs pb subtils (ex: comme tout lock il faut se poser la question du unlock en cas de pb ou d’arret inattendu et là ça se mord la queue).

Bref c’est bien dans les tuyaux depuis les origines mais c’est resté en bas de la pile jusqu’ici.

Ok merci de la précision… J’avais donc une idée fausse de ce qui se passait sous le capot…
J’ai voté :pray:

En l’état l’ensemble des noeuds effectue l’upgrade en // ce qui est dommage mais ne pose pas de pb (les patches sont écrits de telle manière qu’ils puissent être rejoués sans erreur avec des blocs XML en if="[not ]exists", idem pour les patches SQL qui - si la syntaxe SQL de la base le permet - sont écrit avec des IF [NOT ]EXISTS)

1 Like

Une idée :

Je démarre, je m’enregistre dans PlatformNode.
Je cherche le lock d’auto-upgrade en base.

Si il y en a déjà un et que ce n’est pas moi-même qui l’avait déposé, j’attends la fin de l’installation en checkant régulièrement la présence du lock. Au bout d’un certain temps d’attente si rien ne se passe et que le propriétaire du verrou n’est pas joignable, je passe quand même les patchs et je retire le verrou.

Sinon je pose un verrou qui m’identifie (comme pour le master des cron uniques), je déroule les patchs, et je retire le verrou dans un finally.

En cas de crash violent (pas de finally) je serai encore le seul à pouvoir installer les patchs au redémarrage dans un temps imparti.

Si personne ne redémarre jamais parce que mon OVH a brulé, il faudra retirer le verrou à la main en base. Mais ça c’est déjà le cas pour celui qui a le verrou de la cron unique par exemple (1 cas connu en 10 ans).

Le problème est général à toutes les synchros inter-noeuds = clear-cache global, désactivation d’un user qui kill toutes les sessions… utilisent la table de Operation/PlatformNode qui est sensée contenir les URL uniques des noeuds du clustter.

Chaque noeud s’y enregistre au démarrage, et se retire quand il s’arrête ou quand il ne répond plus depuis un autre noeud. Sans avoir d’identification des noeuds, on ne pourra rien faire, les noeuds ne sont pas seuls au monde mais bien inter-connectés pour de nombreuses raisons.

On peut pas plutôt éviter les comportements implicites? Si y’a le moindre comportement inattendu => fail. Sinon on risque d’avoir des bugs en aval dont on aura du mal à identifier l’origine…

  1. Au démarrage, suppression auto des éventuels locks, avec warning la cas échéant (process à part? faut peut-être se renseigner sur la bonne solution)
  2. La première instance qui réussi à poser le lock passe les patchs
  3. Si ça bloque, “hang” du démarrage => on sera notifié par les ops si ce genre de comportement se répète souvent, et on pourra itérer sur la solution

Autre piste plus “low level” à creuser = visiblement les containers Docker (y compris sur K8S) peuvent partager des IPC (shared mem & sémaphores) et je pense qu’il existe des libs Java qui encapsulent ça.

Je vais creuser de ce coté car il pourrait y avoir d’autres usages de ce type de com “bas niveau” interprocess.

Non ça se mord la queue. la seule solution est de nommer celui qui a le lock pour qu’il ne se supprime pas lui-même. Et il faut toujours concevoir des systèmes qui s’auto-corrigent (cf les loaders qui corrigent les paramétrages étranges avec des warnings), et puis les fails seront des tickets sur ce forum.

Oui si Simplicité ne devient pas trop dépendant à une seule architecture.
Il est préférable d’avoir des solutions agnostiques aux couches d’en dessous quand c’est possible.
Et là c’est la cas.

Il y a aussi des implémentations de sémaphores “high level” reposant sur des caches partagés (genre Redis), ça oblige à ajouter un composant au déploiement mais ça pourrait potentiellement servir à d’autres choses liées au multi-noeud à l’avenir.

Pour être pragmatique voyons déjà si une solution standalone qui utiliserait uniquement la base de données serait bien viable dans 95% des cas, ensuite on verra comment adresser les 5% de cas tordus (ex: service I/O dédié, etc.).