About

This page contains a single entry from the blog posted on October 29, 2007 7:07 PM.

The previous post in this blog was System-Statusanzeige.

The next post in this blog is Ein Bisschen GUI muss sein....

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.31

« System-Statusanzeige | Main | Ein Bisschen GUI muss sein... »

Konfigurationsmanagement

Eine wesentliche Funktion, die das Kernmodul von Consolvix bereit stellen soll (und die es in der Tat mittlerweile tut ;-)), ist das einheitliche Auslesen und Speichern von Programmeinstellungen (AppSettings). Beispiele hierfür sind etwa die Anzahl der standardmäßig anzuzeigenden Einträge in einer Liste, das default-Homeverzeichnis der Hostingkunden, die UID des Mailservers und vieles mehr. Angefangen hatte es also mit einer Tabelle in der Form

appsettings(id_, key, value).

Doch um etwas mehr Übersicht zu schaffen, ist es natürlich sinnvoll, die einzelnen Werte an das jeweilige Modul zu binden, wo sie ihre Gültigkeit erhalten. So würde es z.B. wenig Sinn ergeben, die default-Webroots der Webbenutzer zu laden, wenn man sich gegenwärtig im Modul "email" aufhält. Und wenn man schon von verschiedenen Modulen spricht, die ja auch noch in verschiedenen Versionen auftauchen können, kommt zusätzlich gleich noch eine Versionierungsinformation hinzu. Also wird aus der obigen Tabelle die folgende:

appsettings(id, key, value, version, moduleid).

Nebenbei bemerkt, die Modul-Tabelle sieht so aus:

consolvixmodule(id, name, description, version, isenabled?, navigationentry, controllername, created_at)

Es war so angedacht, dass bei einem Update über das [version]-Feld entschieden werden sollte, ob ggf. eine neuere Modulversion zum Download zur Verfügung steht. Wenn diese dann installiert wäre, so würde dann (je nach antwort auf die Frage ob die alte Config übernommen werden soll) für jedes AppSetting ein neuer Eintrag mit identischen/aktualisierten Attributen und der neuen Versionsnummer (der des neuen Moduls) angelegt werden. Das würde Downgrades einfacher machen, denn die alten Einstellungen blieben weiterhin erhalten.

Aber sowas kann man ja genausogut über das Datum machen: dieses wird nämlich beim Herunterladen der Modulliste vom Downloadserver gleich mitgeliefert.

Dieses Konzept geriet arg ins Wanken, als ich heute die Funktion zum Auslesen der Konfigurationswerte weiter auscodete. Um einen Hauch dessen zu vermitteln, was da auf mich zugekommen wäre, möchte ich nur die API-Kommentare anführen, die ich (VOR! dem Erstellen der Funktion) dazu schrieb:

class ApplicationController < ActionController::Base @@module_name = 'core'

# Get an application setting, optionally with module name and version.
# * setting_name: the name of the setting to be retrieved, either string or symbol
# * module_name: name of the module where to look for the setting.
#              If none specified, use current module.
#              If not found, return default value or throw exception (see options)
# * options: Optional ;-)
#  * :version (Integer) => look for this version.
#                          If none specified or 0, use current module version (default)
#                          If positive, look for this exact version (return default value or throw exception if not found).
#                          If -1, look for highest version available.
#                          If not found, raise not found exception (if no default value given)
#  * :default (Object)  => return this value instead of throwing an exception
#  * :core (true|false) => let the core option take precedence over the default value, if specified.

def setting(setting_name, module_name=@@module_name, *options)
  # ...
end

end

Das hätte schätzungsweise 50 zeilen Code bedeutet und irgendwie schien mir die Herangehensweise etwas dubios. Irgendwie so wie "hole dir den wert einer Einstellung, wenn du sie hier nicht findest schau mal dort, oder dann vielleicht drüben, oder sonstwo, notfalls bei 'ner alten version die eigentlich gar nicht mehr existieren sollte -- und wenn das alle snix wird, dann schmeiß eben 'ne Exception". Toll, was? :)

Also wenn Konfigurationsmanagement, dann bitte auch vernünftig. Das ist nun herausgekommen: Benenne "version" in "configuration_id" um. Mache eine neue Entität Configuration und lasse für jedes Modul sauber angelegte Konfigurationen zu, die ein Admin nach Belieben zusammenstellen und aktivieren/deaktivieren kann. Wenn ein neues Modul installiert wird, so kann entweder eine neue Konfiguration angelegt werden, oder allenfalls neu hinzugekommene AppSettings werden einfach in die bestehende Konfiguration übernommen. Wenn bestimmte Einstellungen in der neuen Modulversion nicht mehr verwendet werden, dann stören sie auch keinen, wenn sie weiterhin in der Datenbank herumgeistern (es gibt da allerdings auch eine "Cleanup Module Configuration"-Option ;-)). Die configurations-Tabelle schaut so aus:

configurations(id, name, description, moduleid, userid, createdat, updatedat)

Es folgt nun ein Wenig Pseudocode, der in etwa klar machen soll, nach welchen Regeln nun Einstellungen geladen werden:

if modulname_angegeben? and modul_vorhanden?(modulname)
  modul = modulname
else
  if not core_option_angegeben? and modul_vorhanden?(@@module_name)
    modul = @@module_name
  elsif core_option_angegeben?
    modul = 'core'
  end
end
if modul.nil?
  raise "Modul nicht vorhanden"
end

if einstellung_vorhanden?(für_modul) and modul != core
  return einstellung(für_modul)
elsif core_option_angegeben? or modul == core
  if einstellung_vorhanden?(für_core)
    return einstellung(für_core)
  end
end
if default_option_angegeben?
  return :default
end
raise Exception(nicht gefunden)

Die Versionsnummer taucht nirgends mehr auf, darum kümmert sich wie gesagt nun das Configuration-Objekt. Damit lassen sich Konfigurationen auch benennen. Beispielsweise ist es damit auch möglich, während Wartungsphasen den Zugriff au alle Module durch Auswahl einer entsprechenden Konfiguration zu sperren. Ach überhaupt ist vieles denkbar. Ich denke mal, dass sich heute wieder einiges an Flexiblität in der Anwendung etabliert hat ;-)

TrackBack

TrackBack URL for this entry:
http://www.innoq.com/movabletype/mt-tb.cgi/2845

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)