Zu diesem Zweck hab ich mir von Oreilly 3 Bücher heruntergeladen und bin diese überflogen, um die Konzepte zu verstehen. Die in den Büchern vorgestellten Datenbanken verwendeten die sogenannte Gremlin Query Language. Trotzdem muss ich sagen: Ich war skeptisch – wie ich bei sehr vielen NoSQL Datenbanken skeptisch bin. Es gibt sicher einige gute (Cassandra, Redis, …) – aber viele scheinen mir auch klassische Sonntagsprojekte zu sein und haben niemals den Tiefgang und die Professionalität von e.g PostgreSQL.
Dabei kann man diverse Schritte zwischen C# und IL analysieren und auch manipulieren (in Form von Ergänzung). Die Manipulation macht unter anderem bei Aspekt orientierter Programmierung Sinn, wenn man Cross-Cutting-Concerns auslagern will. Das ging bis dato nur mit PostSharp gut. Vor- und Nachteile wurden hier im Detail abgehandelt. Ich habe Roslyn für die Analyse von Source-Code verwendet. Es funktioniert sehr gut. Die Challenge ist eher der Kompilierprozess per API – der ist ein wenig wackelig.
PostgreSQL unter Windows 10 Windows 10 mit Docker Desktop und WSL2 funktioniert einfach super. Man hat die Einfachheit von Windows gepaart mit der Power von Linux. Auf dem Entwicklerrechner habe ich daher:
version: "3.1" services: db: image: postgres command: ["postgres", "-c", "logging_collector=on", "-c", "log_directory=/var/log/postgresql", "-c", "log_filename=postgresql.log", "-c", "log_statement=all"] restart: always environment: POSTGRES_PASSWORD: postgres volumes: - postgres-volume:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql ports: - 5432:5432 volumes: postgres-volume: Gerichteter Graph Aufgabenstellung war die Speicherung eines gerichteten Graphen inklusive Informationen pro Kante. In SQL schaut es wie folgt aus:
Durch Zufall hat es sich heuer ergeben, dass ich eine Vorlesung am Technikum-Wien übernehmen konnte. Das Thema Softwarekomponentensysteme ist ein Thema, welches mich interessiert und ich hatte eine konkrete Vorstellung, was ich darüber erzählen würde. Damit die Folien nicht untergehen, hab ich mich dazu entschlossen, sie auch hier online zu stellen. All in All war es eine (zeitaufwendige) Challenge – aber durchaus auch eine lehrreiche.
Anmerkung: Ich musste neben der Vorlesung alle Folien und Übungen machen - vermute, es sind noch einige Fehler drinnen - bzw. würde ich noch ggf. einiges überarbeiten.
Ich habe im Laufe meiner Entwicklerzeit schon einiges gesehen. Leider musste ich extrem viele Stunden mit dem Analysieren von Bugs verbringen. Dabei waren für mich immer die angenehmsten Bugs, wenn eine Exception geflogen ist nach dem Motto „Das habe ich in diesem State nicht erwartet“. Der Fehler war schnell zu verstehen und schnell behoben. Aber dann gibt es diese Bugs wo man dran sitzt und keine Ahnung hat … Wie kam die Software in diesen State? Wie kann ich es überhaupt reproduzieren? Kann ich es überhaupt reproduzieren?
Oft sind die trivialsten Themen jene, die – wie es so schön heißt – versumpern. Und es sind auch jene Themen, die dann am Ende des Tages – durch den häufigen Einsatz – am meisten Kopfweh machen. Nach dem 100sten Bug, den man analysiert hat – akribisch – fast wie ein Detektiv – kommt zum Schluss: das hätte alles nicht so sein müssen – ich hätte mir viel Arbeit erspart, wenn es der Entwickler „besser“ gemacht hätte. Ein Thema ist: Exception Handling.
Neben Exceptions ist Threading ein weiteres Thema, welches viel Kopfweh bereiten kann. Bei Exceptions hat man oft gute Erfolgschancen zu verstehen, was schief gegangen ist. Bei e.g. Race-Conditions schauts relativ schlecht aus. Man kann es oft lokal nicht nachstellen oder sieht nur die Auswirkung – die Ursache zu finden ist dann meist unmöglich. Neben den Bugs gibt es aber auch positive Aspekte: die Applikation wird performanter, denn moderne CPUs haben viele Kerne.
Im Laufe meiner Arbeitskarriere bin ich immer wieder auf 1 Problem gestoßen: Komponente A hat einen State, andem andere Komponenten interessiert sind. Ich hab schon die unterschiedlichsten Lösungen gesehen:
DataTables mit RowChanged und anschließend über .NET Remoting Events raus WCF Events .NET Sync-Framework Auch habe ich im Laufe meiner Arbeitskarriere immer wieder die gleichen Probleme gesehen:
Bug gemeldet: State in Komponenten X passt nicht: erwartet wurde State 1 - aber State ist 2. Wie kam es zu State 2? Was waren die vorhergehenden States? Als Entwickler kann man jetzt die Log durchforsten und sich die Stimuli von Komponenten X “raussuchen” und hoffen, dass man es irgendwie nachstellen kann. Aber im Regelfall kann man nur mit der Schulter zucken - vermutlich Events durcheinander gekommen. Bug gemeldet: “komisches Verhalten” - es scheinen Events zu fehlen. Das durchschauen der Logs lenkt den Verdacht auf Verbindungsverluste / Service-Neustarts / … Das System steht: Self-Denial Attacks [1] ist der Klassiker. Eine Zentrale Komponente, bei der sich andere Komponenten registrieren. Startet diese neu, kommt es meist zu einem Neu-Subscriben - oft umgesetzt mit Snapshot-Delta Strategie. Das belastest dieses zentrale Komponente enorm. Ab und zu ist der Betreuer des Systems dazu gezwungen, Services manuell “langsam” zu starten, damit die zentrale Komponenten nicht “versagt”. Ich hab daraus drei Dinge gelernt:
Weihnachtszeit und etwas Zeit sich irgendwas anschauen – da muss auch ein wenig Platz für Entwicklung sein. Diesmal: Wie könnte man einen Teil eines Actor Frameworks im C# Style mit möglichst wenig Aufwand schreiben? Es gibt nichts schlimmeres im Code als ein Threading Massaker. An 1000 Stellen Thread.Run oder new Thread – da läufts jedem Entwickler kalt den Rücken runter, wenn der nächste Bug in Jira anflattert und nur ein Hauch von Race-Condition Problemen aus der Beschreibung herauszulesen ist („Nicht mehr reproduzierbar“, „passiert nur manchmal“ usw.).
Erste Station RabbitMQ RabbitMQ ist ein etablierter Message Broker, welcher in Erlang geschrieben ist. Erlang ist für hoch parallele Applikationen interessant, da es jeden Core der CPU mehr als gut ausnutzen kann (1 Thread pro Core – Erlang Prozesse kann man Millionen machen – siehe Actor Modell). Wie funktioniert RabbitMQ?
Quelle: https://www.cloudamqp.com
Dieses Bild zeigt die Funktionsweise:
Eine Nachricht wird an einen Exchange geschickt. Anhand von konfigurierten Bindings wird die Nachricht an eine Queue weitergeleitet: