26. September 2005

Mein Content Management System

Es heisst jeder Kuenstler macht in seinem Leben mindestens eine Madonna, als Skulptur oder als Bild. Was dem Bildkuenstler die Madonna ist, ist dem Programmierer das Content Managmenent System. Jeder Programmierer schreibt mal eins. Deshalb gibt es Content Management Systeme, wie Sand am Meer. Weil ich nicht der erste sein will, der mit der Tradition bricht, habe auch ich in den letzten Tagen ein CMS geschrieben.

Name: SCMS (= Simple CMS)
Features: Templates, CSS/DOM Pagegenerator, News, RSS, Weblog, Extensions.
Besondere Kennzeichen: einfach, keine Datenbank.
Kommentar: alle Dateien im HTML Editor editierbar, auch die Content-Dateien. Pagegenerator verwendet Decorator-Pattern.

Wer es haben will, bitte melden bei wolf@bluehands.de. Es wird nicht veroeffentlicht, weil es damit sicher bleibt. Security by obscurity. Die letzte Rettung, wenn man bei "Standardsoftware" von Hackern geplagt wird. SCMS bleibt geheim und sicher.

_happy_coding()

20. September 2005

Protokoll bluehands Seminar 20.09.2005

Thema: Logging Strategie

Das Thema Loggin hat viele Dimensionen. Folgende Punkte wurden diskutiert:

  • Logging in Applikationen vs. Logging in Libraries: Libraries sollten nicht selbst bis zur Oberflaeche loggen, sondern ihr Logging an die Host-Applikation delegieren (callback, delegate).
  • Tracing: zusaetzlich zum Logging braucht man manchmal Tracing, d.h. jede Methode meldet Einsprung und Aussprung.
  • Multithread-save Logging
  • Loglevel: wir verwenden folgende Loglevel: Fatal, Error, Warning, Debug, Info, Verbose, Trace, VeryVerbose
  • Bedeutung der Loglevel sollte ueber eine gesamte Applikation hinweg aehnlich sein.
  • Channels; Logging braucht Channels damit Logging-Quellen getrennt (gefiltert) werden koennen. Man will zB nicht eine gesamte Applikation auf VeryVerbose schalten, sondern nur eine Klasse oder ein Modul. Der Klassen name als Channel ist ein guter Ansatz. Das muss dann manchmal verfeinert werden.
  • Syslog/EventLog: Logging auf einen Systemdienst.
  • TCP/MsgQ: Logging auf eine Netzwerkverbindung an einen Logserver.
    Logging sollte immer mitgefuehrt werden, nicht erst, wenn es Probleme gibt oder gar nach dem Deployment.
  • Problem und Loesung von Logging in Libraries ist verwandt mit Konfiguration in Libraries.
  • Daten fuer Verbose und VeryVerbose levels sollten nur dann erzeugt werden, wenn entsprechende Level aktiviert sind.

Loglevel-Bedeutungen bei bluehands:

  • Fatal: wenn die Applikation beenden muss
  • Error: Fehler, der zum Funktionsabbruch fuehrt
  • Warning: Fehler oder schlechte Datenlage, die behoben werden kann
  • Debug: temporaerer Level fuer printf-Debugging. (Auskommentieren, drin stehen lassen)
  • Info: regelmaessige (wichtige) Systemzustaende und Aenderungen
  • Verbose: Verarbeitungsverlauf, 10-100 Zeilen pro Sekunde
  • VeryVerbose: 1000 Zeilen pro Sekunde
Logging Klassen sind bei bluehands fuer C# und C++/C standardsisiert.

_happy_coding()

16. September 2005

Rechner gehackt

Vielleicht! Im Logfile stehen POST /xmlsrv/xmlrpc.php und einige "Maximum execution time of 30 seconds exceeded in /home/web/wwwroot/www.webmob.de/blogs/b2evocore/_functions_xmlrpc.php on line 402"

Es lebe die selbstgeschriebene Software.

Tja, plattmach.

8. September 2005

Protokoll bluehands Seminar 08.09.2005

Thema: Binary Encoding und String Encoding

base64: Encoding, um binaere Daten in ASCII zu codieren, sodass sie durch ASCII Protokolle uebertragen werden koennen, z.B. SMTP (Email) oder XML. Je 3 Byte Ausgangsdaten werden so auf 4 Byte verteilt, dass das hoechste Bit 0 bleibt und keine ASCII Steuerzeichen vorkommen.

Unicode: Unicode ist eine standardisierte Aufzaehlung von Zeichen aus allen moeglichen Zeichensaetzen dieser Erde. Alle Zeichen bekommen eine Nummer. Zufaellig absichtlich liegen die ASCII Zeichen in den niedrigen Nummern auf den gleichen Plaetzen, wie man es von ASCII gewohnt ist.

Microsoft Unicode Implementierung: MS hat beschlossen, dass Unicode Strings aus Zeichen zu je 2 Byte bestehen (Typ: short). Dabei vernachlaessigt MS bewusst Unicode Zeichen mit Nummer ueber 64k. Alle Strings im NT/XP/Vista Kernel sind in Unicode im Memory dargestellt.

UTF-8: Unicde Transfer Format, mindestens 8 Bit, manchmal mehr. ASCII Zeichen werden mit einem Byte dargestellt, alle anderen mit mehr als einem Byte, z.B. MS Unicode mit 2 Byte. So wird z.B. ö als ö dargestellt.

Weitere Themen: PPP, SLIP encoding, Modem, Escape Sequenzen, ISO/OSI Modell.

_happy_coding()

2. September 2005

Auto beleidigt

Mein Auto ist beleidigt, weil ich es verkaufen wollte. Es hat gemerkt, dass was in der Luft liegt. Ich hatte den Fahrzeugbrief herausgesucht und neuen TÜV gemacht, obwohl der erst in einem Jahr faellig gewesen waere. Und weil mein Auto sich in seinem Alter nicht mehr an jemand anders gewoehnen will, stellt es sich jetzt tot. Ploetzlich ist die Kupplung kaputt, verliert Wasser und Oel und die Bremsen sind hin. Jahrelang hatte es nichts. Ich habe es nicht verwoehnt, alle 30.000 km Oelwechsel musste reichen, aber ich habe es mit Achtung behandelt. Das hat es mir gedankt durch reparaturfreies Fahren bis 219.000 km. Aber anscheinend will es nicht verkauft werden. Dann kommt es jetzt zum Abdecker. Pech.

_happy_coding() trotzdem

Nachtrag: Das Abschiedsbild.

Protokoll bluehands Seminar 02.09.2005

Thema: select und asynchrone Socket Kommunikation

Normalfall bei einfachen Netzwerkanwendungen sind Systemcalls in der Reihenfolge: socket, connect, write, read. Wenn man auf mehrern Verbindungen gleichzeitig komunizieren will, dann kann man dafuer 2 Threads machen, die jeweils connect, write, read machen. Das gilt fuer Server, die normalerweise viele Verbindungen haben (read/write vertauscht) oder Clients mit Verbindungen an mehrere Server. Aktuelles Beispiel: der Jabber Bot, der mehrere LLuna User simuliert.

Es gibt aber Faelle, wo Threads nicht angebracht sind. Dazu gehoeren Server mit sehr vielen Clients (bei 100 Threads hoert der Spass auf) oder Frameworks, die kene Threads haben PHP). Manche wollen auch auf Threads verzichten, weil Threads eine Synchronisationsproblematik erzeugen, die nicht alle Programmierer vollstaendig ueberblicken (kein Witz).

Es stellt sich die Frage: wie macht man "read" auf 2 sockets gleichzeitig obwohl beide blockieren. Antwort: select. Es gibt versciedene Arten von Select auf verschiedenen Betriebssystemen und Frameworks, select auf Posix, WSAsyncSelect auf Windows, socket_select in PHP, etc.

Allen gemeinsam ist, dass man eine Liste von Sockets angibt, an denen man interessiert ist und einen Timeout. Select wartet solange, bis auf mindestens einem Socket etwas passiert (z.B. Daten ankommen) oder bis der Timeout ablaeuft.

Die Anwendung von select ist einfach. Angenommen man macht eine Anwendung, die nur regelmaessig Sockets schreibt und dann immer sleep() macht:

while (1) {
write(data)
sleep(2 sec)
}

Jetzt ersetzen wir sleep() durch select(). Der Timeout bleibt und dazu kommen die Sockets, fuer die wir uns interessieren beim read():

while (1) {
write(data)
select(socketlist, 2 sec)
}

Select sagt wie viele Sockets Daten fuer uns haben. Dann koennen wir auf den angezeigten Sockets read() machen (ohne ausseres while):

n = select(socketlist, 2 sec)
if (n > 0) {
foreach (socketlist as socket) {
read(socket);
}
}

Select kommt dann zurueck, wenn der Timeout ablaeuft oder wenn mindestens ein Socket signalisiert. Es kann also sein, dass select() nicht so lange wartet, wie angegeben. In diesem Fall muss man einfach nochmal select() aufrufen und die Restzeit als Timeout angeben. Dazu misst man die Zeit, die vergangen ist im select() und den nachfolgenden read(). Das Ergebnis sieht so aus:

timeout = 2;
while (timeout > 0) {
starttime = currenttime()
n = select(socketlist, timeout)
if (n > 0) {
foreach (socketlist as socket) {
read(socket);
}
}
endtime = currenttime()
timeout -= enddtime - starttime
}

Es fehlt noch einiges fuer eine reale Anwendung. Die Zeit muss in Microsekunden verarbeitet werden. Also z.B. gettimeofday() als Zeitmessung. Fehlerbehandlung natuerlich auch.

Wenn wir schon dabei sind: man sollte auch write() nicht blockierend machen. Wann man schreiben darf, sagt auch das select(). Dazu hat das select() in Wirklichkeit nicht nur eine Socketliste, sondern mehrere. Der innere Teil sieht dann etwa so aus:

n = select(readlist, writelist, exceptionlist, timeout)
foreach (readlist as socket) {
read(socket);
}
foreach (writelist as socket) {
write(socket);
}

Das bedeutet natuerlich: alles was man write()n will, in eine Queue haengen, und select sagt dann, wann man schreiben darf.

Weitere Themen waren Netzwerkkommunikation in Verbindung mit User I/O, Windows Events, Windows: WaitForMultipleObjects(), MsgWaitForMultipleObjects(), Posix: errno

_happy_coding()