wissenslogs Mehr als Bits und Bytes

Software-Evolution...

von Rainer Gerhards, 24. März 2009, 18:42

Haben Sie schon einmal darüber nachgedacht, wie Software sich entwickelt? Welche Stufen Sie durchläuft? Für proprietäre Software ist das natürlich schwierig, aber Dank Open Source können wir ja heute sehr weitgehend Einblick in die Entwicklungshistorie nehmen. Und, wie ich finde, einige Interessante Schlüsse daraus ziehen.

Im "richtigen Leben" entwickele ich Software, eines meiner zur Zeit wichtigsten Projekte ist rsyslog, ein Dienst der Systemnachrichten protokolliert (so etwas gehört zu jedem Unix/Linux, aber kaum jemand interessiert sich dafür, geschweige denn, hat es jemals bewusst genutzt...). Das Projekt existiert seit einigen Jahren und hat mittlerweile eine recht zufriedenstellende Verbreitung gefunden.

Ich habe mir Gestern einmal Zeit genommen, einen groben Überblick über die Versionshistorie des Projekts zu erstellen. Prinzipiell verfolgen wir mit rsyslog die Strategie, neue Versionen möglichst rasch an die interessierten Nutzer auszuliefern. Dieser Kreis ist klein, leistet aber sehr wichtige Arbeit in Bezug auf erste Praxistest sowie Feedback, um das Projekt auf der richtigen "Marschrichtung" zu halten. Frisch herausgegebene neue Versionen mit neuen Feature sind im Regelfall noch recht fehlerbehaftet und nicht für den Produktiveinsatz geeignet. Daher gibt es verschiedene Entwicklungszweige in rsyslog: den sogenannten Development Zweig, der immer den neuesten Code beinhaltet - und damit natürlich am fehlerbehaftesten ist. Ist die Entwicklung für ein Feature abgeschlossen, so wird der Code in den sogenannten Beta-Zweig übertragen. Dort kann er in Ruhe "reifen". Hier werden nur noch Fehler behoben, aber keine neuen Features mehr hinzugefügt. Dadurch wird im Regelfall ebenfalls verhindert, dass neue Fehler hinzu kommen. Im Laufe der Zeit gibt es daher immer weniger Fehlermeldungen, und irgendwann kommt der Punkt an dem eine Version als "stabil" deklariert wird (übrigens ein im Open Source Umfeld oft sehr subjektives Qualitätskriterium). Zu diesem Zweck wandert der Code bei rsyslog dann in einen so genannten Stable Zweig. Ab jetzt erscheint er tendenziell zum Produktivbetrieb geeignet.

In rsyslog halten wir übrigens mehrere dieser "stable"-Versionen vor, und zwar eine je Hauptversionsnummer. Man erkennt hier schon das Konzept unterschiedlicher "Stabilitäten" - denn der älteste, am längsten eingesetzte Code ist wahrscheinlich doch stabiler als der, der gerade erst freigegeben wurde. Er kann dafür halt auch wesentlich weniger. Das aber nur als Detail am Rande.

Dieser Zyklus aus Development-Beta-Stable wiederholt sich die gesamte Entwicklungszeit.
Neue Features werden dabei prinzipiell immer nur in der aktuellen Development-Version hinzugefügt. Man kann daher getrost von verschiedenen Entwicklungslinien innerhalb der Codebasis sprechen. Und nun wird es Zeit, mein Diagramm ins Rennen zu schicken (eine größere Version findet sich auch auf meiner privaten Webseite):



In den Kreisen (Knoten genannt) stehen dabei immer die Versionsnummern oder Bezeichnungen der Zweige (mehr dazu später). Durchgezogene Linien stellen direkte Nachfolgebeziehungen dar, bei Gestrichelten habe ich ob der Übersichtlichkeit einige Zwischenversionen ausgelassen.  Die roten Pfeile stellen die Hauptlinie, den Development-Zweig dar. Blaue Pfeile sind die Stable Versionen (man beachte die unterschiedlichen Versionsnummern!). Schwarze Verbindungen bezeichnen Beta- und sonstige Zweige.

Ganz unten im Diagramm sind die Haupt-Entwicklungslinien bezeichnet
: "devel" (für Development), "beta", "v3-stable", "v2-stable" und "v1-stable". Die Linie v1-stable ist dabei nur noch gestrichelt dargestellt: das hat seinen Grund darin, dass sie seitens des Projekts nicht mehr offiziell unterstützt wird. Dieser Zweig ist so alt, dass wir nicht mehr erwarten, ihn noch in der Praxis anzutreffen. Im rsyslog-Zoo handelt es sich quasi um eine ausgestorbene Gattung. Allerdings: der Code existiert noch, er ist weiter im Projekt enthalten und sollte jemand ganz dringend Korrekturen an dieser Version benötigen (und uns hinreichend bestechen ;)), so könnten wir die Version wieder "auferstehen" lassen. Einige Feinheiten der sich auch weiter entwickelnden Systemumgebungen sowie der daraus resultierenden "Problemchen" seinen hier charmant verschwiegen - der geneigte Leser möge darüber nachdenken, inwieweit die nicht mehr vorgenommene Anpassung einer inaktiven Version an die sich ändernde Umgebung ein allgemeines Problemfeld darstellt.

Ganz oben startet das Diagramm mit einem als "sysklogd" bezeichneten Knoten. Dies ist der "Urvater" aller rsyslog-Versionen: "sysklogd" war lange Zeit der Standard-Protokolldienst unter Linux. Aus verschiedenen hier nicht zu erläuternden Gründen haben wir seinerzeit einen so genannten "Fork" von diesem Programm gemacht, d.h. dessen Code benutzt, um daraus eine gänzlich neue, wesentlich erweitere, Entwicklungsschiene (eben rsyslog) zu beginnen. Übrigens existiert auch sysklogd heute immer noch, seine Bedeutung in der Praxis geht aber, nicht zuletzt dank rsyslog, kontinuierlich zurück. Und auch sysklogd hat eine komplexe Historie und wurde meines Wissens nach ursprünglich aus einem anderen Projekt "geforkt" (hat sich aber zumindest ein anderes Projekt zum Vorbild genommen). Der ursprüngliche syslogd entstand übrigens in den frühen 1980ern im Rahmen des sendmail-Projekts. Man sieht hier sehr schön, wie auch Software-Entwicklung über Projektgrenzen hinaus fortschreitet.

Zurück zu rsyslog: im Diagramm sind auch noch einige gestrichelte Knoten, die Namen wie "perf", "test" oder "solaris" tragen. Dies sind sogenannte "Feature-Zweige". Hier wird von einem Zweig (meist auf der Hauptlinie) eine Unterzweig abgespalten, in dem dann eine spezielle Entwicklung erfolgt. Es gibt sehr viel mehr dieser Entwicklungszweige, als in der Grafik aufgeführt sind. Insbesondere kann die Entwicklungszweige dreierlei Schicksal erleiden: entweder sie sind erfolgreich, dann werden sie, oft erst viele Versionen später, wieder in einen der Hauptzweige (meist Devel) integriert. Im Beispiel trifft das auf "tests", "perf" und "file-errHdlr" zu.

Dann gibt es Entwicklungszweige, die einfach nicht das gewünschte Ergebnis erzielen und nie wieder in eine der offziellen Linien eingehen. Das geschieht z.B. dann, wenn ein Feature sich in der Praxis nicht bewährt, als unsinnig heraus stellt, der Code aus irgend welchen Gründen nicht die notwendige Mindestreife erzielt, sich eine Aufgabe als zu komplex heraus stellt oder die Realisation eines größeren Features einen vorherigen kleineren Entwicklungszweig obsolet macht. Ein guter Kandidat hier in der Graphik für einen solchen Zweig ist "msgnolock", der im Wesentlichen ein sehr experimentelles Verfahren implementierte und vermutlich künftig durch etwas Anderes ersetzt werden wird. Solche Zweige verbleiben oft für längere Zeit im Code. Dabei können sich Phasen, in denen wieder aktiv an Ihnen gearbeitet wird mit Phasen auch längerer Inaktivität abwechseln. Auch zu dieser Gruppe, aber mit einem gewissen Sonderstatus, gehören Zweige wie "debian_lenny", die gezielt geschaffen wurden, um einen bestimmten Versionsstand, der nicht zu den Hauptzweigen gehört, weiter betreuen zu können. Debian_lenny ist beispielsweise der Stand, der in Debian 5.0 eingeht. Auch wenn das keine direkt Hauptlinie (sondern eine "Unterart" von v3-stable) ist, so ist diese Version doch hinreichend wichtig, um als eigenen Entwicklungslinie gepflegt zu werden. Dieser Zweig wird aber niemals mehr mit den Hauptlinien gemischt werden, da das gerade seinem Zweck zuwider laufen würde.

Womit wir gewissermaßen bei der dritten Klasse der Feature-Branches angelangt wären: den Toten. Debain_lenny un v1-stable werden wohl dauerhaft im Code verbleiben, auch wenn sie irgendwann vielleicht gar nicht mehr nutzbar sein werden. Kleinere Entwicklungszweige trifft aber ein anderes Schicksal: sie werden nach einer gewissen Frist schlichtweg gelöscht und sind dann unwiederbringlich verloren. Dieses radikale Mittel wird man natürlich nur mit Vorsicht anwenden - mithin könnte man Teile des Codes später doch noch benötigen, vielleicht in gänzlich anderem Zusammenhang. Aber es gibt gute Gründe, gewisse Zweige dann doch endgültig zu "beerdigen". Häufig passiert das übrigens mit Zweigen, die man erst gar nicht im öffentlichen Code-Speicher findet. Wenn man bei der Entwicklung etwas nicht-triviales probiert, dann spaltet man im Regelfall einen neuen Unterzweig ab. funktioniert der Test, vereinigt man diesen Zweig wieder mit dem, aus dem er abgespalten wurde. Und zwar dergestalt, dass man den Unterzweig nicht mehr als eigenständigen Zweig erkennen kann. Führt der Unterzweig aber nicht zum gewünschten Ergebnis, so kann man ihn einfach verwerfen. Das ist durchaus üblich, ich habe zum Beispiel gerade eben noch einen gewissen Misserfolg mit der Integration von Code-Korrekturen gehabt. Der dafür angelegte Unterzweig ist schon längst wieder verworfen, und morgen wird das "Experiment" mit einem frischen Zweig von vorne begonnen. Den alten zu reparieren wäre viel zu lästig gewesen, also lieber weg damit und her mit einem neuen. Solche Test-Zweige bieten sich zu allen möglichen Gelegenheiten an, und es muss keinesfalls immer ein Fehlschlag zu ihrer "Vernichtung" führen - vielleicht wollte man nur etwas "quick and dirty" ausprobieren, das klappte, und nun macht man es dann "vernünftig". Der Testzweig hat einem dann viel Arbeit gespart, ist aber für eine professionelle Lösung nicht brauchbar. Wie man jetzt vielleicht schon vermutet, stellen solche "toten Zweige" die weitaus größte Menge der im Leben eines Softwareprojekts entstehenden Zweige überhaupt dar...

So, nun haben Sie es geschafft. Genug von rsyslog und seiner Entwicklung. Aber kurz noch 'mal zurück zum Titel dieses Blogposts: "Software-Evolution..." schrieb ich da - was ich mir dabei wohl gedacht habe... ;)

Ähnliche Artikel:


antworten

Artikel kommentieren
 authimage

Kommentare

  1. Dr. Alois Palmetshofer Evolution und tote Hunde
    24.03.2009 | 19:34

    Die Analogien zu biologischen Evolutionsprozessen sind offensichtlich. einzlne Mikroveränderungen (Punktmutationen, Rearrangements etc). Module (informatorische Entitäten) werden übernommen, bei höherer Komplexität zu neuen "Rassen", erst ohne Probleme kompatibel mit dem Ausgangsprodukt, später mit entprechenden Spezies- und vor allem Kreuzungsbarrieren ...

    Viel vom Neuen wird auch bei sich ändernden Umweltbedingungen keine Chance haben und scheitern, aber so ist das eben. Der Weg zum Erfolg ist gepflastert mit gescheiterten Versuchen, gerichtet oder auch nicht, das ist hier nicht Thema der Debatte. Try and error, mit dem Vorteil der Verstärkung vorteilhafter Strategien (natürlich oder technisch, künstlich), Entitäten und Komplexität. Kleine Veränderung mit fundamentalen Konsequenzen, fast immer fatal, nur im Ausnahmefall von Vorteil, na und??

    Und: Die "Evolution der Software hat eine biologische Basis, oder ist sie eine kulturelle Facette der Evolution?? Die Gesetzmäßigkeiten sicher natürlich, so oder so....

szmtag