Hintergrund
Ich arbeite in einem Team, das Bereitstellungen ohne Ausfallzeiten implementieren möchte. Wir planen eine blau / grüne Bereitstellungsstrategie, um dies zu erreichen. Eines der Dinge, die mir bei der Recherche klar werden, ist, wie kompliziert es wird, Datenbankänderungen vorzunehmen. Ein einfacher Vorgang wie das Umbenennen einer Spalte kann 3 vollständige Release-Zyklen dauern, bis sie abgeschlossen ist!
Es scheint mir, dass die vollständige Einführung einer Änderung mehrere Veröffentlichungszyklen in Anspruch nimmt und viel Potenzial für menschliches Versagen mit sich bringt. In dem verlinkten Artikel wird gezeigt, dass Codeänderungen für 2 Releases erforderlich sind und eine Datenbankmigration für 3 Releases erforderlich ist.
Was ich suche
Derzeit können wir, wenn wir uns daran erinnern möchten, etwas zu tun, ein Ticket in unserem Issue-Management-System erstellen, das Unordnung schafft und möglicherweise auch zu einem späteren Sprint oder dem Rückstand des Managements übergeht. oder wir können einen TODO-Kommentar erstellen, der wahrscheinlich komplett vergessen wird.
Was ich suche, ist eine Möglichkeit, dass ein TODO-Kommentar eine Deadline haben kann, und unser Continuous Integration-System (derzeit unentschlossen, welches wir verwenden) würde den Build ablehnen, wenn diese Deadline abgelaufen wäre.
Wenn wir beispielsweise eine Spalte umbenennen, können wir die ursprüngliche Migration für sie erstellen und anschließend zwei TODO-Kommentare, um sicherzustellen, dass die verbleibenden zwei Migrationen erstellt werden:
// TODO by v55: Create migration to move constraints to new column, remove references to old column in app
// TODO by v56: Create migration to drop old column
Dies scheint ziemlich einfach zu implementieren zu sein, aber ich frage mich, ob so etwas bereits existiert, weil ich das Rad nicht neu erfinden möchte.
Zusätzliche Gedanken
Ich habe das Gefühl, dass ich hier möglicherweise unter einem XY-Problem leide, da fortlaufende Bereitstellungen und blau / grüne Bereitstellungen als bewährte Methoden angesehen werden. Es scheint seltsam, dass ich keine Lösung finden kann, um Datenbankaktualisierungen weniger schmerzhaft zu gestalten. Wenn Sie der Meinung sind, dass ich mich komplett mit dem Falschen befasse, lassen Sie es mich bitte in einem Kommentar wissen! Das Datenbankbeispiel, das ich gegeben habe, ist jedoch nur ein Beispiel, und ich denke, dass TODO-Kommentare mit Fälligkeitsterminen auch in anderen Situationen nützlich sind. Selbst wenn ich mich dieser speziellen Situation ganz falsch nähere, würde ich wirklich gerne auf meine antworten eigentliche Frage auch. Vielen Dank!
EDIT: Ich dachte gerade an eine andere Situation, in der dies hilfreich sein könnte. Wenn Sie Feature Toggles verwenden, um Teile Ihrer App zu aktivieren, wenn sie bereit sind, müssen Sie darauf achten, sie zu bereinigen, da Sie andernfalls möglicherweise Toggle Debt erhalten . Kommentare mit Fristen könnten eine gute Möglichkeit sein, sich daran zu erinnern.
quelle
TODO <Bug#>:
Workarounds für Probleme mit anderen Komponenten nachverfolgen können . Wenn ein Fehler in einer dieser Komponenten behoben ist, können Sie die entsprechenden Problemumgehungen leicht finden und beheben. Es ersetzt keinen Issue Tracker und erleichtert die Wartung.Antworten:
Diese Frage ist wirklich zwei Fragen in einer.
Todo kommentiert
Dies ist die schlechteste Möglichkeit, Aktionselemente zu verfolgen. TODO-Kommentare eignen sich gut für die aktive Arbeit oder als Anregung für einen Betreuer: "Hier ist etwas, das möglicherweise in Zukunft verbessert werden könnte." Wenn Sie sich jedoch auf TODO-Kommentare verlassen, um die Arbeit zu erledigen, sind Sie zum Scheitern verurteilt.
Was tun?
Bei TODO-Kommentaren handelt es sich im Grunde genommen um technische Schulden. Sie sollten daher wie jede andere technische Schuld behandelt werden. Nehmen Sie sie sofort in Angriff, wenn Sie Zeit haben, oder stellen Sie sie in den Rückstand, damit sie nachverfolgt und priorisiert werden können.
Im Allgemeinen können TODO-Kommentare als Code-Geruch betrachtet werden, und dies ist völlig einsichtig und offen für Debatten. Wenn ein TODO-Kommentar es bis zum Einchecken in die Versionskontrolle schafft, müssen Sie sich fragen, ob Sie ihn jetzt tatsächlich ausführen werden? Wenn nicht, ist das in Ordnung. Sei einfach ehrlich zu dir selbst und schreibe es in den Rückstand.
Wie Sie diesen Rückstand bewältigen, hängt vom Geschäftsprozess, der Unternehmenspolitik und möglicherweise von einer gewissen persönlichen Autonomie ab. Sie benötigen jedoch weiterhin einen nachverfolgten und priorisierten Rückstand, um sicherzustellen, dass dies geschieht.
Datenbankänderungen
Ja, Datenbankänderungen sind schwierig, da keine Ausfallzeiten gelten. Einige Tricks, um die Schmerzen zu lindern:
Post-Deployment-Prozess
Erstellen Sie einen Post-Deployment-Prozess, der als Teil derselben Version ausgeführt wird. Sie möchten jedoch, dass es funktioniert. Auf dem letzten System, an dem ich gearbeitet habe, habe ich eine 4-Phasen-Bereitstellung entworfen:
Die Idee war, dass wir, wo immer möglich, so viele Datenbankänderungen wie möglich in Preapp umsetzen.
Postapp war für die ungewöhnlichen Fälle reserviert, in denen wir inkompatible Schemaänderungen vornehmen mussten. In diesen Fällen würde die Voranwendung eine ausreichende Menge an Änderungen vornehmen, um den neuen Anwendungscode kompatibel zu machen (möglicherweise wird eine temporäre Ansicht zur Kompatibilität erstellt), und die Nachanwendung würde solche temporären Artefakte bereinigen.
Die Wartungsfensterphase war Änderungen vorbehalten, die Ausfallzeiten erforderten oder bei denen sich das Risiko oder die Kosten einer Live-Bereitstellung nicht gelohnt hatten. Beispielsweise müssen Skripts, die große Datenmengen ändern, möglicherweise eine gesamte Tabelle sperren.
Häufig bereitstellen
Wenn Sie häufig genug neue Releases bereitstellen, können Sie einen Punkt erreichen, an dem das Übertragen einer Änderung auf zwei oder drei Releases trivial ist. Lange Veröffentlichungszyklen erhöhen die Kosten für Datenbankänderungen.
quelle
Verwenden Sie keine TODOs. Sie haben bereits eine TODO-Liste in Ihrem Projekt. Es heißt Issue Tracker.
Ich denke, das eigentliche Problem liegt in diesem Satz:
Wenn Ihr Issue-Tracker zu viele Probleme verursacht, suchen Sie nach Möglichkeiten, dies zu beheben. Vielleicht eine Sonderausgabe, die weniger Zeremonie erfordert. Vielleicht Unterprobleme. Vielleicht weniger Zeremonie insgesamt. Wir können es nicht wirklich sagen. Wenn Ihr Issue-Tracker jedoch so viel Arbeit verursacht, dass die Leute in einem öffentlichen Forum eher eine ausführliche Frage formulieren, als nur dieses Problem hinzuzufügen, stimmt etwas nicht.
Wenn Ihr Management den letzten Teil einer Aufgabe übermäßig verzögert, haben Sie zwei Möglichkeiten:
Sprechen Sie mit Ihrem Management, warum dies eine schlechte Idee ist.
behandeln Sie es als eine einzige Aufgabe. Dies könnte die Goldstandardlösung sein. In einer perfekten Welt sollten Sie in der Lage sein, die drei in jedem Schritt erforderlichen Änderungen vorzunehmen. Wenden Sie einen Zweig auf den Master-Zweig an, lassen Sie ihn erstellen und bereitstellen. Wenden Sie in der Zwischenzeit die zweite auf den Master-Zweig an, lassen Sie ihn erstellen und bereitstellen und so weiter, damit alles im selben Sprint abläuft. Wenn dies nicht der Fall ist, wird dies nicht ausgeführt. Vielleicht macht sogar etwas Automatisches Sinn, wenn Sie logischerweise eine Bereitstellung durchführen, aber es ist tatsächlich in 3 aufgeteilt.
quelle
// TODO(#12345): Frobnicate the sprocket before passing it along
, vorausgesetzt, Fehler # 12345 ist eine "echte" Ausgabenummer und die Ausgabe ist jemandem zugewiesen. Dies erleichtert das Lesen der Quelle, indem klargestellt wird: "Nein, der Frobnikat-Schritt verbirgt sich nicht in einer der Hilfsmethoden, sondern ist einfach unimplementiert. Weitere Informationen finden Sie unter Fehler # 12345." Im Idealfall wird die Codebasis täglich nach geschlossenen oder ungültigen Ausgabenummern durchsucht.Was Sie verlangen, ist machbar, wenn Sie bereit sind, die Arbeit zu erledigen und durchzuhalten.
grep für
//TODO by v55
wann es Zeit ist, v55 bereitzustellen. Deploy Build führt ein Skript aus, das dies als Integrationstest ausführt.Sie können 55 in Ihre Versionsverfolgung einbinden oder nur danach fragen.
Es wird interessant, wenn Sie bei 55 nach // TODO by v54 suchen möchten. Suchen Sie stattdessen 55-mal in der Codebasis nach // TODO by. Filtern Sie das Ergebnis dann nach 1 bis 55. Jetzt löst 56 keinen Fehler aus.
Sie könnten denken "Oh, das werden wir nicht brauchen. Wir werden dies jedes Mal beheben, solange wir den Scheck haben". Nein, wirst du nicht.
quelle
Wir hatten ein sehr ähnliches Problem in unserem Team. Um dieses Problem zu lösen, haben wir eine statische Analyseprüfung geschrieben, die diese TODOs durch Überprüfen des JIRA-Problems oder des Git-Problems, auf das sie verweisen, behandelt. Unser Build schlägt fehl, wenn das angegebene Problem über die Spalte "In Entwicklung" hinausgeht.
Deshalb können wir bequem TODO's haben, ohne uns Sorgen machen zu müssen, dass sie vergessen werden.
Ich habe eine Open-Source-Implementierung davon in Java erstellt. Ja, ein Haftungsausschluss ist, dass ich das geschrieben habe, aber wie ich schon sagte, es ist komplett Open Source und lizenziert.
Das Tool heißt Westie und ein Beispiel für den Jira-Issue-Checker finden Sie in der README.md. Siehe auch den GitIssueAnalyser.
Wenn Sie weitere Fragen haben, senden Sie mir eine Nachricht, um die Eigenwerbung zu verhindern. Wenn Sie es verwenden möchten und Vorschläge haben, wenden Sie sich bitte an github.
quelle
Nicht zu tun. Mach es jetzt.
TLDR: Schreiben (und testen) Sie Ihre DB-Skripte jetzt und nicht später. Codieren Sie sie einfach, damit ihre Ausführung von der DB-Version abhängt.
Beispiel
Stellen Sie sich zum Beispiel vor, Sie möchten einen Spaltennamen von
SSN
in ändern. DiesTaxID
ist eine häufige Anforderung, wenn Sie international arbeiten.Um dies zu erreichen, haben Sie möglicherweise vorübergehend eine
TaxID
und eineSSN
Spalte. Und während beide Versionen unterstützt werden, haben Sie einen Auslöser, um eine Aktualisierung von der anderen durchzuführen. Sie möchten diesen Auslöser jedoch nicht auf unbestimmte Zeit beibehalten. Wenn später keine Rückwärtskompatibilität mehr erforderlich ist, möchten Sie, dass dieser Auslöser entfernt wird (und dieSSN
Spalte gelöscht wird). Wir werden das alles im Voraus codieren, ohne ToDo-Elemente zu benötigen.In unserem Beispiel werden wir Build 102 (mit der neuen Spalte) implementieren und gleichzeitig die Kompatibilität mit Build 101 (ohne diese Spalte) aufrechterhalten.
Hier sind die Schritte.
1. Richten Sie die Versionierungstabelle ein
Fügen Sie eine einzelne Tabelle
Configuration
mit zwei Spalten hinzu,Name
undValue
.Fügen Sie eine Zeile mit
Name
der Bezeichnung "TargetVersion" hinzu und stellen Sie dieValue
auf die Version des neuen Builds ein, der bereitgestellt werden soll.Fügen Sie eine Zeile mit dem
Name
Wert "CompatibleWith" hinzu, und legen SieValue
die Mindestversionsnummer fest, mit der die Bereitstellung kompatibel sein muss.Überprüfen und aktualisieren Sie diese Zeilen vor jeder Bereitstellung.
2. Ändern Sie die Bereitstellungsskripts
Fügen Sie ein Skript hinzu, das
TaxID
nebeneinander eine neue Spalte von erstelltSSN
und diese aus derSSN
Spalte auffüllt. Schließen Sie diesen Code in eineIf
Anweisung ein, die TargetVersion überprüft. Wenn die Zielversion zu niedrig ist (dh dieTaxID
noch nicht benötigt wird), überspringen Sie.Fügen Sie ein Skript hinzu, das einen Auslöser erstellt, der
TaxID
beim Einfügen oder Aktualisieren ausgefüllt wird,SSN
und umgekehrt. Fügen Sie diesen Code in eineIf
Anweisung ein, die die Zielversion und die kompatible Version überprüft. Überspringen, wenn TargetVersion zu niedrig ist (dasTaxID
wird nicht benötigt) oder wenn die CompatibleWith-Version zu hoch ist (dasSSN
Feld wird nicht benötigt).Fügen Sie ein Skript hinzu, um die
SSN
Spalte zu entfernen . Fügen Sie eineIf
Anweisung ein, die die Spalte nur dann entfernt, wenn die CompatibleWith-Version hoch genug ist (SSN
nicht mehr benötigt wird).3. Testen
Stellen Sie sicher, dass Sie Ihre Bereitstellung mit einer beliebigen Kombination von Blau- / Grün-Versionsnummern testen, die Sie in der Produktion unterstützen möchten. Sie können testen, sobald der Code fertig ist, indem Sie die
Configuration
Tabelle in Ihrer QA-Umgebung bearbeiten.4. In Ihrem Bereitstellungs-Playbook
Fügen Sie einem Bearbeiter einen Schritt hinzu, um die Zeilen CompatibleWith-Version und TargetVersion zu aktualisieren. Wenn Sie auf Blau bereitstellen, setzen Sie TargetVersion auf die Versionsnummer von Blau und CompatibleWith auf die Versionsnummer von Grün. kehren Sie sie um, wenn Sie Green einsetzen.
Fallstricke
Es ist in Ordnung, dass Ihre Implementierungsskripten auf die in dieser DB-Tabelle enthaltenen Versionsnummern verweisen und sich darauf verlassen. NICHT Laufzeitcode.
Wenn Sie mit dem Schreiben Ihres Laufzeitcodes beginnen, um die Versionsnummern zu überprüfen, führt dies zu einer neuen Komplexität in Ihrer Anwendung, die möglicherweise zu einem großen Problem bei der Wartbarkeit führen kann. Jeder Laufzeit-Ausführungspfad muss getestet werden. Wenn Sie diese Zustände in Zukunft fortführen, muss die Qualitätssicherung eine Schmerzmatrix zusammenstellen , um sie bei jeder Veröffentlichung zu validieren. Mein Rat ist, Bedingungen wie diese nur in Bereitstellungsskripten beizubehalten.
Das Ergebnis all dessen
Am Ende sollten Sie in der Lage sein, den gesamten Code im Voraus zu schreiben (und ihn auch zu testen), ohne befürchten zu müssen, dass er zu früh ausgeführt wird. Außerdem bereinigt der Code den Abwärtskompatibilitäts-Trigger, wenn der Zeitpunkt gekommen ist, ohne dass Sie sich weitere Sorgen machen müssen.
Auf diese Weise können Sie den gesamten Code im Voraus schreiben und testen, wenn Sie darüber nachdenken, und müssen sich nicht mit diesen unordentlichen Aufgabenkommentaren befassen.
quelle
Ihre TODO-Idee stößt auf großen Widerhall, aber ich persönlich sehe kein Problem damit. Am Ende besteht der beste (und einfachste) Weg, um sicherzustellen, dass die Migration in die Produktion geht, darin, einen Komponententest nicht zu bestehen, wenn dies nicht der Fall ist. Es dauert buchstäblich weniger als eine Minute, um eine leere Migrationsfunktion zu löschen, die eine Ausnahme auslöst, wenn die Version 55 oder höher ist (oder welche Anforderungen auch immer).
Wenn Sie dann versuchen, es freizugeben, ist der Test fehlgeschlagen, und jemand muss diese Ausnahme in einen tatsächlichen Migrationscode umwandeln.
quelle
Niemand scheint sich auf die Wurzel seiner Beschwerde zu konzentrieren, die darin besteht, dass Datenbankänderungen zu viele Veröffentlichungszyklen in Anspruch nehmen können. Er möchte seinen blau / grünen Bereitstellungsplan fortsetzen, und die Lösung sollte bereits vorhanden sein. Wenn ich jedoch etwas vermisse, scheint seine Beschreibung darauf hinzudeuten, dass es nur eine Datenbank gibt, die von beiden Systemen gemeinsam genutzt wird. Kein echtes Blau / Grün-System, wenn das der Fall ist. Da es den Anschein hat, dass die Datenbank der lange Pfahl im Zelt ist, sollte sie auch dupliziert werden, damit die Datenbankänderungen auf dem Offline-System unabhängig von der Dauer oder der Anzahl der Veröffentlichungszyklen erst nach Abschluss und in Betrieb genommen werden vollständig getestet. In der Zwischenzeit können Offlinesystem-Skripte die Offlinedatenbank täglich vollständig aktualisieren.
quelle