On a livré le support de beads v1.0.0. Il a fallu un rollback, un bug de flock et 6 hotfixes.
Le 2 avril, beads a sorti v1.0.0. La fonctionnalité phare était embedded Dolt : un backend zéro-config qui exécute la base de données dans le processus, sans serveur séparé à gérer. Pour les développeurs solo, c'était la promesse de bd init et c'est tout. Pas de ports, pas de daemons, pas de configuration.
On a commencé à ajouter le support dans Beadbox immédiatement. Six hotfixes, un rollback public et une plongée profonde dans le code source de bd plus tard, on en est sortis avec une couche de résilience qu'on aurait probablement dû construire il y a des mois.
Le matin avant que tout casse
La journée a commencé proprement. On avait mené une chasse au code mort dans toute la codebase et livré v0.20.0 avec 5 350 lignes supprimées et une amélioration de 2 secondes au démarrage à froid. Quarante-deux beads fermés. Un bon matin.
Puis nous avons mis à jour bd vers 0.63.3, le premier release construit sur le backend embedded Dolt de beads v1.0.0.
Beadbox ne trouvait plus la base de données. Le mode embedded stocke les données dans .beads/embeddeddolt/ au lieu de .beads/dolt/. Le nom de la base a aussi changé, de beads codé en dur à un préfixe projet lu depuis metadata.json. Et bd sql, que notre serveur WebSocket utilisait pour la détection de changements en O(1) via DOLT_HASHOF_TABLE, n'est pas du tout supporté en mode embedded.
Trois hypothèses cassées dans les dix premières minutes.
Six releases en un jour
Découvrir, corriger, livrer, redécouvrir.
v0.20.1 a ajouté la persistance des credentials via le keychain de l'OS (six beads de travail déjà en cours), corrigé un bug de filtre de statut personnalisé et patché des problèmes spécifiques à Windows.
v0.20.2 a appris à Beadbox à lire dolt_database depuis metadata.json pour trouver la base de données renommée.
v0.20.3 a ajouté des gardes pour le mode embedded. Chaque appel à bd sql a été enveloppé d'une vérification : si on est en mode embedded, retomber sur du polling CLI au lieu de requêtes SQL directes. La fonction getDoltDir a appris à chercher d'abord dans embeddeddolt/.
v0.20.4 a corrigé la normalisation des chemins --db pour le layout embedded. Les chemins qui marchaient avec l'ancienne structure de répertoires cassaient avec la nouvelle.
Chaque fix révélait le problème suivant.
Le flock
Après v0.20.4, on pensait être stables. Puis on a lancé un simple test de concurrence : cinq appels bd list en même temps.
Quatre ont échoué.
Embedded Dolt acquiert un verrou exclusif de fichier (flock) sur la base de données pour toute la durée de chaque commande. De PersistentPreRun à PersistentPostRun, rien d'autre ne peut y toucher. C'est voulu. Sans ça, l'initialisation concurrente du moteur provoque un nil-pointer panic (beads#2571). Le flock empêche le crash. Mais ça signifie aussi qu'en mode embedded, bd est effectivement mono-processus.
Beadbox n'est pas mono-processus. Notre serveur WebSocket sonde les changements chaque seconde. L'UI lance plusieurs server actions au chargement de la page. Un utilisateur qui navigue dans l'app pendant que le poller de fond tourne va générer des appels bd concurrents. Le flock les bloque tous sauf le premier.
Le post de blog DoltHub sur l'implémentation embedded décrivait le comportement prévu : les appelants concurrents devraient "s'aligner naturellement avec un backoff exponentiel." Mais arch a examiné le code source livré et trouvé que bd utilise TryLock avec LOCK_NB (non-bloquant). Ça n'attend pas. Ça échoue immédiatement. Il y a deux couches de verrou : le flock de bd en haut, et le backoff au niveau driver de Dolt en dessous. La première couche court-circuite la seconde. La logique de retry existe dans la codebase, mais ne s'exécute jamais parce que le flock rejette la connexion avant que le backoff de Dolt ait une chance de s'activer.
Le fix (verrous partagés pour les opérations de lecture via FlockSharedNonBlock) existe dans le code source de bd. Il n'est juste pas encore branché.
C'est le probleme que Beadbox resout.
Visibilite en temps reel sur ce que fait toute votre flotte d'agents.
On pouvait continuer à livrer des hotfixes contre une cible mouvante, ou reculer et construire une vraie couche de résilience. On a reculé.
Tous les releases v0.20.x ont été retirés du repo public. v0.19.0 est revenu comme version recommandée. On a publié une discussion expliquant ce qui s'était passé et quoi faire, et ajouté un bandeau sur beadbox.app. Trente minutes de la décision à la fin.
Chaque heure qu'un release cassé reste en ligne est une heure où quelqu'un le télécharge, tombe sur le problème de flock et blâme le produit. On préfère expliquer un rollback que déboguer la mauvaise première expérience de quelqu'un d'autre.
On n'était pas les seuls
Pendant qu'on déboguait, un utilisateur de beads nommé Kevin a posté beads#2938 : "Beads feels painful to use." Il avait passé 9,5 heures à déboguer des problèmes qui incluaient exactement la confusion embedded-vers-serveur qu'on rencontrait. La mise à jour vers v1.0.0 avait silencieusement basculé son workspace du mode serveur au mode embedded (beads#2949), cachant ses issues existants derrière une base de données fraîche et vide.
9,5 heures. Un utilisateur expérimenté, pas un débutant. Si c'est l'expérience pour quelqu'un qui connaît bien beads, le problème n'est pas l'utilisateur. C'est le chemin de migration.
Ce qu'on a construit pour v0.21.0
Au lieu de patcher des échecs individuels, on a construit une couche qui traite la contention de verrous comme une condition de fonctionnement normale.
Flock retry avec backoff exponentiel. Chaque appel au CLI bd réessaie jusqu'à 5 fois, 100ms à 1,6 secondes entre les tentatives. Vit à un seul endroit dans lib/bd.ts, donc chaque commande en bénéficie gratuitement. Ça couvre le cas courant : deux appels entrent en collision, l'un attend brièvement, les deux réussissent.
UI de dégradation gracieuse. La contention de verrous ne signifie plus un écran d'erreur. L'app affiche des données obsolètes avec un indicateur de rafraîchissement. Si la contention persiste au-delà de 30 secondes, un bandeau ambre explique la situation. Quand le verrou se libère, le bandeau disparaît et les données se rafraîchissent automatiquement.
Suggestion d'auto-promote. La contention répétée déclenche une suggestion de migration vers le mode serveur : sauvegarde, réinitialisation avec --server, restauration. Un clic. C'est la bonne réponse pour quiconque fait tourner Beadbox aux côtés d'autres consommateurs bd, et maintenant l'app vous le dit au lieu de vous laisser le découvrir.
Détection du mode embedded.getDoltDir vérifie embeddeddolt/ et route en conséquence. Les appels bd sql sont protégés. Le pipeline WebSocket retombe sur du polling CLI en mode embedded (plus lent, mais respecte la contrainte mono-processus).
Ce qu'on a appris
Embedded Dolt est mono-processus par conception. Pas un bug. Le flock empêche de vrais panics. Tout outil consommant un workspace beads en concurrence doit sérialiser l'accès ou tourner en mode serveur. Pour Beadbox, le mode serveur est le bon défaut. Embedded fonctionne pour un usage léger avec la couche de retry qui absorbe les collisions occasionnelles.
La doc décrivait l'intention, pas l'implémentation. Le blog DoltHub parlait de backoff. Le code disait TryLock avec LOCK_NB. On a passé du temps à supposer que les lectures concurrentes devaient marcher parce que la documentation le disait. Lire le source a résolu la confusion en minutes. Quand le comportement ne correspond pas à la doc, lisez le code.
Testez la concurrence avant de livrer. On n'a pas exécuté d'appels bd concurrents avant que v0.20.4 soit public. for i in {1..5}; do bd list & done; wait aurait détecté le problème de flock avant tout release. Cinq secondes de test nous auraient épargné un rollback.
Faites un rollback tôt. L'instinct de continuer à avancer est fort. Vous êtes proche, vous voyez le fix, encore un release. Mais chaque release cassé qui reste public est un retrait de confiance qu'on ne peut pas facilement annuler. Revenir à v0.19.0 nous a donné l'espace pour construire la couche de résilience correctement au lieu de la livrer par incréments paniqués.
Vérifiez vos variables d'environnement. On a perdu des heures parce que BEADS_DIR pointait bd vers le mauvais workspace. bd découvrait une base de données différente de celle que Beadbox surveillait, et les symptômes ressemblaient à de la corruption de données. Si vos commandes bd retournent des résultats inattendus, env | grep BEADS avant toute autre chose.
Où on en est
v0.21.0 est sorti avec le support de beads v1.0.0, la couche de résilience et la persistance des credentials via le keychain de l'OS. La discussion du release contient tous les détails.
Si vous êtes sur beads v1.0.0 avec le mode embedded et rencontrez des échecs intermittents, la couche de retry de v0.21.0 devrait gérer ça. Si vous faites tourner Beadbox aux côtés d'autres outils qui accèdent au même workspace, passez en mode serveur. Le flux auto-promote le fait en un clic.
Et si vous êtes Steve ou quelqu'un de l'équipe beads qui lit ça : des flocks partagés pour les lectures corrigeraient la cause racine en amont. beads#2939 (Unix domain sockets) rendrait aussi les connexions locales plus propres. On continuera à construire autour de ce qui sera livré.
Essayez par vous-même
Commencez avec beads comme couche de coordination. Ajoutez Beadbox quand vous avez besoin de supervision visuelle.
Gratuit pendant la bêta. Aucun compte requis. Compatible natif avec Dolt.