Let it Crash: Paradigma für fehlertolerante, massiv-parallele Software

Seite 3: Fazit

Inhaltsverzeichnis

Jedes sinnvolle und erfolgreiche Paradigma findet seine Nachahmer. Zum Beispiel kann man Erlang auch auf der JVM betreiben. Das Portierungsprojekt heißt Erjang. Zwar hat es experimentellen Status, doch es lässt sich trotzdem damit erfolgreich zeigen, wie man sehr viele parallele Aktoren so laufen lassen kann, dass das Paradigma befolgt wird.

Ein noch prominenteres Beispiel ist die Akka-Bibliothek, die es für Java gibt, vor allem aber in Kombination mit Scala ihre Stärken ausspielt. Jemand, der den historischen Sachverhalt nicht kennt, könnte sich darüber wundern, wie viel Erlang in Akka enthalten ist. Das Kopieren und Erweitern war aber beabsichtigt, weil das Paradigma und die damit verbundenen Konzepte sich in kritischen produktiven Systemen bereits bestens funktionieren.

Hier ein kleiner gemischter Ausschnitt dessen, wie man mit Akka/Scala Actors (die in Scala nun mal so heißen, im Gegensatz zu Erlangs Prozessen) startet und sich mit ihnen verlinkt.

// link and unlink actors
self.link(actorRef)
self.unlink(actorRef)

// starts and links Actors atomically
self.startLink(actorRef)

// spawns (creates and starts) actors
self.spawn[MyActor]
self.spawnRemote[MyActor]

// spawns and links Actors atomically
self.spawnLink[MyActor]
self.spawnLinkRemote[MyActor]

Und auch die Konzepte von Erlangs OTP-Behaviours haben Einzug in Akka/Scala gehalten.

val supervisor = Supervisor(
SupervisorConfig(AllForOneStrategy(
List(classOf[Exception]),3,1000),
Supervise(
actorOf[MyActor1],
Permanent) ::
Supervise(
actorOf[MyActor2],
Permanent) ::
Nil))

Bevor man das "Let it crash"-Paradigma in Betracht zieht, sollte man unbedingt vorher über folgende Fragen nachdenken und auf jede davon mindestens eine Antwort finden:

  • Soll man einen Fehler unbedingt behandeln? "Let it crash" und defensive Programmierung schließen sich nicht aus, sondern ergänzen sich.
  • Wie soll man den Fehler behandeln? Will man einen Fehlerindikator zurückliefern, eine Ausnahme erzeugen, loggen, ignorieren, das ganze Programm beenden?
  • Kann man an der Stelle überhaupt einen Absturz zulassen? Soll man hier fortfahren? Kann man in diesem Zustand überhaupt weitermachen?
  • Kann man nach einem Crash Müll hinterlassen, oder soll man aufräumen?
  • Wenn man einen Programmteil nach einem Fehler nun hochfährt, woher weiß man, dass er nicht wieder und immer wieder abstürzt? Soll man Vorkehrungen gegen einen solchen Fall treffen?
  • Warum vertraut man nicht eigenen Funktionen, die nicht Teil einer öffentlichen API sind und rein intern verwendet werden? Warum erwartet man dort Probleme mit Parametern, wo ausschließlich man selbst Aufrufe tätigt? Sollte man das Problem nicht etwa an einer anderen Stelle lösen? Etwa außerhalb?
  • Soll man den Fehler vor Ort abfangen, oder sollte man lieber auf einen zentralen Fehlerbehandlungsprozess bauen, der alle möglichen Fehlersituationen und die damit verbundenen Reaktionen kennt?
  • Sollte man im Fall von APIs Parametertypen und -werte prüfen? Sollte man deren Semantik testen, einen sogenannten Contract implementieren?

Sind diese Fragen beantwortet, kann der Entwickler es je nach Antworten ruhig krachen lassen – das Paradigma ist für bestimmte Situationen stabil und bewährt.

Pavlo Baron
ist Autor zahlreicher Artikel, Referent auf Konferenzen und Autor der Bücher "Pragmatische IT-Architektur", "Fragile Agile" und "Erlang/OTP". Er arbeitet als Lead Architect bei codecentric. Seine beruflichen Interessen sind verteilte Systeme, Hochskalierbarkeit und große Datenmengen (Big Data).

(ane)