Gestern war noch alles finster: Ein Videoserver, der im ::free so gnadenlos abraucht, dass sogar der Debugger (MSVC) beendet und kein Land in Sicht. Der Videoserver benutzt ffmpeg, das leider nicht im MSVC kompiliert. Deshalb mit cygwin kompilieren, dann LIB generieren aus einem zusammengeschusterten DEF file und .so in DLL umbenennen. Geht, ist aber nicht toll. Vor allem benutzt die DLL dann offensichtlich das cygwin Memory Management, dass unabhaenging ist vom VC++ Memory Management. 1. es braucht die cygwin1.dll und 2. das Memory Management kollidiert in manchen ffmpeg Funktionen. Das geht besser:
Wenn man ffmpeg fuer ein Windows MSVC Projekt will, dann kompiliert man ffmpeg mit MinGW. configure --enable-shared erzeugt anstandslos LIB und DLL fuer avformat und avcodec. Der grosse Vorteil: die DLLs brauchen keine cygwin Runtime, sondern verwenden die MSVC runtime, toll.
Wie installiert man MinGW: Bei mir ist schon Cygwin drauf. Das wird empfohlen, denn dann hat man alle Entwicklungstools einschliesslich make. Dann MinGW-3.1.0-1.exe, danach MSYS-1.0.10.exe. Der heutige ffmpeg CVS-snapshot kompiliert uebrigens nicht mit MinGW. Ich verwende deshalb ffmpeg-0.4.9-pre1.
Und deshalb habe ich heute die perfekte Quelle: MSVC mit ffmpeg.
Nachtrag (01.12.2005): ffmpeg-0.4.9-pre1 hat in Spezialfällen Thread-Synchronisationsprobleme. Die Probleme bei der CVS Version wurden inzwischen behoben. Deshalb verwenden wir jetzt wieder die CVS Version.
_happy_coding_
3. Dezember 2004
Das ist die perfekte Quelle, der perfekte Tag
Neulich auf www.lluna.de
Wolfspelz betreibt Muessiggang und liesst Spiegel Online. Da kommt Kreiz, der Wolfspelz kennt. Sie reden ueber Radeon 9800 usw., gehen dann wieder zusammen auf www.LLuna.de. Dort treffen sie Tine, die Shooter spielt (weiss Wolfspelz, weil er sie vorher schonmal getroffen hat). Wolfspelz stellt Tine und Kreiz vor, weil Kreiz auch ein grosser Shooter-Liebhaber ist. Die beiden reden was Shooter-Spieler halt so reden aus Sicht des Strategie- und Rollenspielers Wolfspelz. Dann gehen sie gemeinsam die Homepages ihrer jeweiligen Clans anschauen.
Toll, wenn die eigene Software Leute mit gleichen Interessen zusammenfuehrt.
(Ja, Muessiggang wird mit ue und ss geschrieben, wenn der Autor Softwarekuenstler ist und eine englishe Tastatur hat. Da liegt das "{" eben naeher, als das "ü")
_happy_coding_
Labels: Virtuelle Präsenz, Zeitgeist
19. November 2004
Nach der Beta ist vor der Beta
Was kann sich eine Entwicklerin mehr wünschen als dass eine halbe Million Experten sich darum reissen, ihre Software zu testen. Ich war einer der 500.000. Ich habe 10 Tage lang ein grossartiges Stück Ingenieursarbeit getestet, und zwar ausgiebig, insgesamt 48 Stunden. Es handelt sich um ein gewaltiges Client-Server System aus mehreren Millionen Klienten an einigen hundert Servern. Jeder Server versorgt tausende von Klienten mit Echtzeitdaten, die von den Aktionen allen anderen Klienten abhängen. Die Klienten sind voller redaktionellem Content, der dynamisch vom Server erweitert wird, fast ohne die Reaktionszeit zu beeinträchtigen. Die Benutzer haben nur eine sehr geringe Störungstoleranz. Das Netzwerk muss deshalb auch bei Lastspitzen verzögerungsfrei arbeiten.
Hunderte von Entwicklern und Künstlern haben mehrere Jahre gearbeitet und offensichlich haben sie Ihre Arbeit ziemlich gut gemacht. Hunderttausende haben das Produkt bestellt, bevor der Preis feststand. Das ganze System wird schon bald für 50. Mio $ Umsatz im Monat sorgen. Die Rede ist von World of Warcraft einem MMORPG.
World of Warcraft ist zwar nur eines von vielen MMORPGs, die gerade entstehen. Aber es ist eines der aufwändigsten. Es ist sicher technisch eines der besten Spiele und es wird vom heimlichen Star der Computerspielbranche produziert: Blizzard. Einem Entwickler und Publisher von dem die User wissen, dass Produkte erst dann fertig sind, wenn sie fertig sind, auch auf Kosten von verpassten Weihnachtsgeschäften. Anscheinend hat es diesmal gerade gereicht. Ach ja: WoW ist schön, aber es gibt bessere Grafik. Half Life 2 ist ...anders.
Jedenfalls ist die amerikanische Beta jetzt zuende. Bald kommt die europäische, dann werde ich wieder ausgiebig testen.
_happy_coding_
10. September 2004
Galactic Developments (Science Fiction eStory)
Galactic Developments ist ein Science Fiction Projekt in Form eines Online-Romans. Es erzählt mögliche Geschichten, wie sie in den kommenden Jahrhunden stattfinden könnten. Sehr detailreich wird beschrieben, wie das Leben auf einem bestimmten Planeten während eines Krieges oder zu Friedenszeiten aussieht. Häufig kommen einem politische Konstellationen oder handelnde Hauptfiguren bekannt vor. Oft spielt Sol, Terra, oder wie auch immer wir uns selbst nennen, eine tragende Rolle. Ein zentrales Thema ist: Geschichte wiederholt sich, auch die Geschichte der Zukunft, aber die Umstände, die Menschen und die Werkzeuge, insbesondere Technologie ändert sich. So ist eines der wesentlichen Themen, mit denen sich Galactic Developments beschäftigt der Technologische Fortschritt und dessen Auswirkungen: "Immer wieder in der Vergangenheit war Technologie entscheidend für die Weiterentwicklung der Geschichte. Wir nehmen an, dass dies auch in Zukunft so bleibt. Technologische Überlegenheit ist vor allem in (wirtschaftlichen und militärischen) Auseinandersetzungen ausschlaggebend."
1. August 2004
Komponentenentwicklung mit Logging und Konfiguration
Jede ernstzunehmende Programmierung braucht zwei Basisdienste: Logging und Konfiguration. Über den Code verstreut findet man Loggingausgaben und Konfigurationsstatements. Meistens wird dabei auf globale Objekte zugegriffen. Das heisst, es gibt in jeder Methode eines Moduls anwendungsspezifischen Code. Ein Albtraum bei der Wiederverwendung in anderen Projekten. Das ist das Logging- und Konfigurationsproblem. Für das Problem gibt es verschiedene Lösungskonzepte.
Jede ernstzunehmende Programmierung braucht zwei Basisdienste: Logging und Konfiguration. Logging sollte in jeder Methode auf jeder Ebene Zustandsinformationen ausgeben. Das ist besonders im Fehlerfall wichtig als Diagnosemittel. Daneben sind aber auch Zustandsinformationen zur Laufzeit wichtig für die Optimierung eines Systems. Flexible Anwendungen lassen sich in vielen Parametern konfigurieren. Dafür verwendet man typischerweise eine Konfigurationsschnittstelle, die im gesamten Programm zur Verfügung steht, ganz ähnlich der Loggingschnittstelle. Über das Modul verstreut findet man Loggingausgaben und Konfigurationsstatements oft als Einzeiler. Das heisst, anwendungsspezifischer Code ist potentiell in jeder Methode eines Moduls vorhanden.
Nur begibt es sich aber, dass oft Module geschrieben werden, die in verschiedenen Anwendungen Einsatz finden. Da passiert es häufig, dass die Logging- und Konfigurations-Schnittstellen (LC=Log/Config) des Moduls nicht zum Programm passen. Wird ein Modul in einer Anwendung entwickelt und dann in einer anderen Anwendung verwendet, kollidieren oft 2 verschiedene LC Schnittstellen.
Eigentlich sollte eine Komponente frei sein von anwendugsspezifischem Code. Exceptions versprechen da Abhilfe, weil diese in einem Modul bis zur Anwendung weitergeworfen werden können. Das hilft aber nicht wirklich, weil ein gutes Modul Fehler lokal behandeln und evtl. kompensieren muss. Ausserdem fehlt der Fehlerstack, wenn eine Exception von ganz unten erst ganz oben gefangen wird. Eine vergleichbare Scheinlösung gibt es auch für die Konfiguration. Module können bei der Initialisierung konfiguriert werden, dann entfällt die Abfrage der aktuellen Konfiguration innerhalb des Moduls. Das ist nicht gut, weil das Module beim Setup alle Parameter speichern muss, was redundant ist, da sie ja schon global gespeichert sind. Laufzeitkonfiguration ist dann auch nicht möglich.
Ergebnis in der Praxis: Module können oft nicht wiederverwendet werden. Natürlich werden in der Praxis Lösungen gefunden, sonst gäbe es keine wiederverwendeten Module. Mögliche Lösungen:
1. Kein Logging, keine Laufzeitkonfiguration: die häufigste Lösung, aber nicht akzeptabel.
2. Klassen mit Loggingsenke/Konfigurationsquelle als Konstruktionsparameter: bedeutet, jede Klasse bekommt und verwaltet Referenzen der globalen Log/Konfig-Objekte. das ist sehr unpraktisch.
3. Plattformdienste, wie syslog (Un*x), Enterprise Instrumentation Framework (Win), Registry (Win): nicht plattform-portabel.
4. Applikationsglobale Objekte, die über Einzeiler benutzt werden: Module funktionieren nicht ohne ihre Applikation und sind nicht einfach wiederverwendbar, da jede Methode angepasst werden muss.
5. Hooks: Einzeiler mit Adaptern
Lösung 5 ist das geringste Übel. Sie ermöglicht Einzeilerlogging/-konfiguration, verzichtet aber auf globale Objekte. Module werden mit modulspezifischen LC-Statements geschrieben und debuggt. Diese Statements werden dann über Adapter an die Applikation angepasst. Die Statements dürfen nicht direkt auf die jeweiligen Funktion gehen, sondern indirekt über einen Adapter, der angepasst werden kann. Erst der Adapter harmonisiert die LC Schnitstelle des Moduls mit der Applikation. Minimale Adapter werden mit den Modulen ausgeliefert, um die problemlose Wiederverwendung zu gewährleisten. Der einzige Nachteil dieser Methode ist, dass man sich auf einen Funktionsumfang einigen muss. Beim Logging muss festgelegt werden, dass ob und dass es Loggingklassen und/oder Kanäle gibt. Bei der Konfiguration muss man sich auf die Struktur der Konfigurationsdaten einigen.
Typische Loggingkonzepte sehen eine Loggingklasse, einen Kontext und eine Meldung vor. Möglicherweise auch noch einen Kanalnamen. Mit diesen Informationen kann man fast alle applikationsspezifischen Loggingsenken zufriedenstellen. Ein Logginstatement sieht dann so aus:
MyLog(ERROR, "Klasse oder Kanal", "Methode oder Context", "Meldung");
Typische Konfigurationsdaten sind hierarchisch aufgebaut. Mit bis zu 3 Ebenen sieht ein Konfigurationsstatement so aus:
value = MyConfig("Level1", "Level2", "Item", DEFAULTWERT);
Oder mit beliebig vielen Ebenen:
value = MyConfig("Level1" "/" "Level2" "/""Item", DEFAULTWERT);
Der minimale Logadapter wird die Meldung verwerfen während der minimale Konfigadapter den Defaultparameter der Bibiothek zurückgibt. Die Adapter werden als Funktionen implementiert, die evt. auch von aussen gesetzt werden können (=Hooks). Adapter müssen zwar implementiert werden. Sie sind aber meistens sehr schlicht und das ist allemal besser, als auf Logging zu verzichten oder jede Methode anzufassen.
Empfehlung: Die Logginklasse sollte Teil des Projektcodes sein. Dann kann man Module inklusive einem funktionierenden Logging weitergeben oder weiterverwenden. Ich verwende nur 2 Dateien, die ich von Projekt zu Projekt kopiere: MyLog.cpp und MyLog.h. Alle Loggingklassen und -instanzen sind mit einem Kuerzel geprefixt. Dann braucht man nur in 2 Dateien das Prefix ersetzen.
_happy coding_
Labels: Code
21. Juli 2004
Grosse Softwareprojekte in der Krise
Die Reihe der Hiobsbotschaften reißt nicht ab. Gerade haben wir den Maut-Schock von TollCollect überwunden. Wir wundern uns noch darüber, dass Herkules, ein Projekt mit Standardsoftware überhaupt scheitern kann. Da kommt die Meldung, dass die Finanzämter vielleicht 900 Mio. Euro ausgegeben haben, ohne Ergebnis. Man muss schon fast fragen, ob es noch staatliche Organisationen gibt, die keine IT-Grossruine haben. Schon lange war jedem klar, dass IT teuer ist. Inzwischen wundert man sich nicht mehr wenn sie auch nicht funktioniert. Wie kann man unter diesen Umständen erwarten, dass Firmen noch IT-Projekte vergeben? Die Großprojekte spielen zwar in einer anderen Liga. Aber der Imageschaden trifft auch den IT-Mittelstand.
Hier die Liste der Problemkinder (Problem-Riesenbabys), die mir gerade so einfallen:
- Herkules - Modernisierung der Informationstechnik der Armee (1400 Mio. -> 6000 Mio.)
- TollCollect - LKW Maut
- Inpol - Polizeiinformationssystem (17,4 Mio. -> 115 Mio.)
- BA online - Stellenbörse der Bundesanstalt für Arbeit (65 Mio. -> 165 Mio.)
- FISCUS - Finanzamt (170 Mio. -> 250 und 900 Mio.) gescheitert
was fehlt? da war noch mehr.
Die Gross-IT scheint sich in einer Krise zu befinden. Funktionieren IT-Projekte generell nicht? Sind die, die funktionieren nur Zufallstreffer? Das kann nicht sein, denn es gibt zu viele Projekte, die funktionieren. Es gibt zig-tausend IT-Projekte, davon Hunderte große und man hört nur von denen, die schief gehen. Aber warum gehen sie schief? Bei vielen der Problemkinder hört man von Managementschwächen. Grundsätzlich kann man davon ausgehen, dass das Management immer schuld ist, denn die Alternative ist, dass die Aufgabe mit dem verhandelten Budget unlösbar war. Das wäre grob fahrlässig auf der einen und betrügerisch auf der anderen Seite. Das wollen wir nicht im allgemeinen annehmen. Also bleibt eine dilettantische Durchführung. Dafür ist das Management verantwortlich. Selbst wenn das Management nicht direkt schuld ist, sondern die ausführenden Hände, so ist das Management doch verantwortlich und muss die ausführenden Hände wahlweise antreiben, motivieren oder austauschen. In Einzelfällen mag das Management wirklich sub-optimal gewesen sein. Man hört ja so manches und wundert sich, wie eine tausendfach vorgenommene Anpassung einer Standardsoftware (Herkules) nicht funktionieren kann. Wie kann die Einführung einer Standardsoftware überhaupt so viel Anpassung erfordern? Wo bleibt der Standard? Oder wie kann man rechtfertigen, Sicherheitsfunktionen bei TollCollect nachzureichen? In einer Welt in der sich sofort tausend Geier auf Sicherheitslücken stürzen, ist Sicherheit so wichtig für das Funktionieren, wie die Funktion selbst.
Trotzdem glaube ich nicht, dass schwaches Management der Grund des Übels ist. Hier kommt die These: Das Managementparadigma ist falsch. IT wird gemanagt wie industrielle Massenproduktion. Bei großen Projekten wird das Arbeitspensum in tausend kleine Stücke zerlegt, die von Programmierern nur noch eingetippt werden müssen. Die Programmierer werden auch Kodierer genannt, weil sie nur noch vordefinierte Funktionen eintippen. Sie müssen vor allem billig sein. Deshalb ist das vorherrschende Paradigma, dass man sie in Billiglohnländern beschäftigt. Wie ein Kollege von mir schon lange kritisiert, gilt anscheinend der Leitspruch: Programmierer ist man nicht, Programmierer hält man sich.
Und das ist falsch. Es gibt Programmierer, die wirklich programmieren. Programmierer, die allein oder mit wenigen Software schaffen, die viele Menschen benutzen. Diese Programmierer wissen, dass Programmieren eine Kunst ist. Programmieren ist eine komplexe Tätigkeit in der die Wahrnehmung und Verarbeitung vernetzten Wissens eine wesentliche Rolle spielt. Richtige Programmierer müssen Code-Künstler (Code-Artists) sein. Programmieren/Kodieren ist nicht analog zur Fliessbandarbeit bei BMW. Sogar die Autohersteller erkennen, dass die Individuen wichtig sind. Lean-Production, kleine Teams, flache Hierarchie, individuelle Kreativität und gute Ausbildung werden als wichtig erkannt. Noch wichtiger sind diese Fähigkeiten beim Softwaredesign. Denn Softwareproduktion ist Design bis ins kleinste Detail. Es gibt keine geplanten Vorgänge, die immer gleich ablaufen, keine Massenproduktion. Software wird auch ganz unten nicht produziert, sondern entworfen und designt. Je weiter nach oben man kommt und je größer das Projekt wird desto mehr wird das Gesamtdesign zur Kunst, zum Orchester. Nur wenige beherrschen die Orchestrierung des Ganzen. Aber sogar die ausführenden Hände müssen Künstler sein. Jeder für sich. Denn wie in einem Orchester kann sich ein schwaches Glied auf das Gesamte auswirken. Die Analogie zur Massenproduktion ist falsch. Sie muss raus aus den Köpfen der nicht programmierenden Manager und derer, die sie ausbilden. Wenn schon eine Analogie sein muss, dann zum Orchester oder zum Entwicklungsprozess beim Automobil. Die Produktion in der Massenfertigung entspricht gerade noch dem Kopieren der fertigen CD und der Verpackung. Aber Softwareproduktion ist Softwaredesign, ist Kunst. Dafür werden Künstler gebraucht, bis ins letzte Glied, wenn möglich. Die Erfahrung zeigt, dass ein Softwarekünstler mehr und besseren Code schreibt als 4 Kodierer. Die 4 Kodierer lohnen sich nicht, nicht einmal, wenn sie in Indien sitzen.
Liebe nichtprogrammierende Menschheit: Wenn Ihr funktionierende IT-Projekte wollt, dann beschäftigt richtige Programmierer mit Weitsicht, Überblick und Liebe zum Detail. Glaubt nicht an das Märchen vom gemanagten Kodierer. Beschäftigt erfahrene Softwarekünstler und wir versprechen euch funktionierende Projekte.
_happy coding_
7. November 2003
On Jabber
ICQ, MSN, AIM: wie Messaging Dienste unter einen Hut gebracht werden. Jabber bietet "all in one" auf Open Source Basis. Nicht nur für Messaging
Oft entsteht gute Software, weil ein Entwickler ein Problem für sich selbst löst und das Ergebnis dann anderen zugänglich macht. Das war sicherlich der Fall bei Jeremie Miller, dem Gründer des Jabber.org Projekts. 1998 war es einfach leid, 4 oder 5 verschiedene Instant Messanger und mehrere IRC Kanäle zu beobachten, um mit seinen Freunden online Kontakt zu halten. So begann er ein neues Instant Message System zu entwickeln, dass mit allen anderen Systemen kommunizieren konnte, sodass die Benutzerin nur noch ein Instant Message Programm braucht.
Im Gegensatz zu den existierenden Instant Message Systemen (ICQ, AIM, MSN, usw.) wurde Jabber von Anfang an auf XML aufgebaut. Die Architektur von Jabber ist sehr ähnlich zu Email: ein Netzwerk von Servern leitet Nachrichten vom Sender zum Empfänger. Auch die Adressen der Benutzer sehen aus wie Email Adressen, z.B. wolf@jabber.bluehands.de. Übermittelt werden meistens kurze Nachrichten (Instant Messages = Kurzmitteilungen). Der zweite wichtige Bestandteil ist die ständige Aktualisierung des Online-Status, damit die Absenderin weiß, ob der Empfänger online ist. Das ist auch der große Unterschied zu Email: Kurzmitteilungen kommen sofort an und man weiß, ob der Empfänger da ist.
Die Kommunikation mit den anderen Instant Message Systemen erledigt ebenfalls der Jabber Server. Der Server wandelt die XML-Nachrichten der Jabber-Klienten in die Protokolle der anderen Instant Message Systemen um und Instant Messages von einem Benutzer im ICQ werden für mich in XML umgewandelt. Auf dieser Weise wird Jabber zum universellen Übersetzer zwischen verschiedenen Instant Message Systemen.
Die Jabber-Klienten müssen nur einfache XML-Nachrichten verarbeiten. Jabber Nachrichten sind meistens kurze XML-Stücke. So sieht eine Kurznachricht in Jabber aus:
<message to="wolf@jabber.bluehands.de">
Hallo Klaus
</message>
So eine Nachricht, teilt Christine mit, dass ich online bin:
<presence to="christine@jabber.bluehands.de">
<status>online</status>
</presence>
Das sind die beiden am häufigsten benutzten Nachrichtentypen. Zusätzlich bietet das Jabber Protokoll viele andere Möglichkeiten, Informationen abzufragen oder auszutauschen. Das Protokoll ist einfach erweiterbar durch XML Namespaces für weitere Anwendungen, wie Börsenticker, Newsheadlines oder beliebige andere strukturierte Daten.
"Schön, aber was bringt mir das?", höre ich Sie sagen. Zuerst einmal: egal welche IM Klienten Ihre Kommunikationspartner verwenden, Sie brauchen nur einen. Und den können Sie aus einer langen Liste wählen. Darüber hinaus wird Jabber immer mehr auch als Messaging Middleware verwendet. Durch die Kombination von einfach zu programmierenden Klienten und einem erweiterbaren Protokoll stößt Jabber auch in die Bereiche der Maschine-zu-Mensch und Maschine-zu-Maschine Kommunikation vor. Das heisst, Sie können mit Ihrem Jabber-Klienten auch den Zustand von Maschinen überwachen oder RPC/SOAP über Jabber tunneln. Im Gegensatz zu HTTP-basierter XML-Kommunikation funktioniert Jabber auch ohne Einschränkungen bidirektional und eventbasiert.
Inzwischen gibt es schon zigtausende Jabber-Server und Millionen Benutzer in der ganzen Welt. Obwohl Jabber noch jung ist, wächst es sehr schnell und entwickelt sich rasant. Die Zeit wird zeigen, ob Jabber's Open Source Technologie die Erwartungen erfüllen kann und zu einem - oder neben HTTP dem - Standardsystem für XML-basierte Echtzeitkommunikation wird.
_happy coding_