{"id":481,"date":"2026-09-24T19:04:34","date_gmt":"2026-09-24T19:04:34","guid":{"rendered":"https:\/\/www.donaldswelt.ch\/?p=481"},"modified":"2026-09-24T19:09:21","modified_gmt":"2026-09-24T19:09:21","slug":"erst-chaos-dann-aha","status":"publish","type":"post","link":"https:\/\/www.donaldswelt.ch\/index.php\/2026\/09\/24\/erst-chaos-dann-aha\/","title":{"rendered":"Erst Chaos, dann Aha"},"content":{"rendered":"<p class=\"PDq2pG_selectionAnchorContainer\" dir=\"auto\" data-section-id=\"1pna2r1\" data-start=\"350\" data-end=\"380\"><strong><span role=\"text\">Die Geschichte dahinter<\/span><\/strong><\/p>\n<p class=\"PDq2pG_selectionAnchorContainer\" dir=\"auto\" data-start=\"346\" data-end=\"736\">Manche Arbeitstage beginnen so, als h\u00e4tten sich alle Probleme f\u00fcr denselben Morgen verabredet. Heute war wieder so ein Tag. W\u00e4hrend einer Inbetriebnahme liefen mehrere Themen gleichzeitig: Hier musste noch etwas verkabelt werden, dort gab es R\u00fcckfragen, an einer anderen Stelle sollte etwas angepasst werden, und zwischendurch wartete schon das n\u00e4chste Problem darauf, angeschaut zu werden.<\/p>\n<p dir=\"auto\" data-start=\"738\" data-end=\"1180\">Zus\u00e4tzlich sollte ich per Fernwartung noch ein anderes Problem untersuchen. Die Verbindung lief dabei \u00fcber das iPhone und war so langsam und tr\u00e4ge, dass vern\u00fcnftiges Debugging praktisch nicht m\u00f6glich war. Normalerweise macht man eine \u00c4nderung, startet einen Test und sieht relativ schnell, was passiert. In diesem Fall bedeutete jeder einzelne Schritt: <strong data-start=\"1091\" data-end=\"1133\">\u00c4ndern, warten, testen, wieder warten.<\/strong> Irgendwann war klar: So wird das heute nichts.<\/p>\n<p dir=\"auto\" data-start=\"1182\" data-end=\"1470\">Also habe ich die Fehlersuche dort relativ schnell beendet und beschlossen, das Ganze sp\u00e4ter im B\u00fcro unter normalen Bedingungen sauber aufzubauen. Manchmal ist es sinnvoller, ein Problem f\u00fcr den Moment liegenzulassen, statt unter schlechten Bedingungen immer mehr Zeit darin zu versenken.<\/p>\n<p dir=\"auto\" data-start=\"1472\" data-end=\"1677\">W\u00e4hrend der Inbetriebnahme war mir aber noch ein anderes Verhalten aufgefallen, und genau diesem Problem widmete ich mich danach. Dabei stiess ich zuerst auf ein interessantes Architekturthema im Webproxy.<\/p>\n<p dir=\"auto\" data-start=\"1679\" data-end=\"1960\">Im normalen Betrieb verwenden wir f\u00fcr verschiedene Controller getrennte Dienste. Jeder Dienst l\u00e4uft damit in seinem eigenen Programmkontext und verbindet sich mit genau dem Controller, f\u00fcr den er vorgesehen ist. Deshalb war ein bestimmtes Verhalten bisher nie wirklich aufgefallen.<\/p>\n<p dir=\"auto\" data-start=\"1962\" data-end=\"2307\">In meiner aktuellen Testkonstellation liefen jedoch mehrere Verbindungen innerhalb desselben Prozesses. Pl\u00f6tzlich zeigte sich, dass ein gemeinsam verwendeter Singleton-Zustand f\u00fcr diese Situation nicht ideal war. Was bei einem einzelnen Controller problemlos funktioniert, wird interessant, sobald mehrere Verbindungen denselben Dienst benutzen.<\/p>\n<p dir=\"auto\" data-start=\"2309\" data-end=\"2462\">Die entscheidende Frage war pl\u00f6tzlich: <strong data-start=\"2348\" data-end=\"2462\">Wem geh\u00f6rt dieser Zustand eigentlich? Controller A, Controller B oder einfach dem ersten, der zuf\u00e4llig da war?<\/strong><\/p>\n<p dir=\"auto\" data-start=\"2464\" data-end=\"2720\">Damit war klar, dass die Verbindungskontexte sauberer voneinander getrennt werden mussten. Kein spektakul\u00e4rer Absturz und kein Weltuntergang, aber ein sch\u00f6ner Fund, weil genau diese spezielle Konstellation das Problem \u00fcberhaupt erst sichtbar gemacht hatte.<\/p>\n<p dir=\"auto\" data-start=\"2722\" data-end=\"2822\">Und dann kam noch der zweite Fehler. Der war deutlich kleiner und im Nachhinein wesentlich lustiger.<\/p>\n<p dir=\"auto\" data-start=\"2824\" data-end=\"3134\">Das Problem sah zun\u00e4chst so aus, als w\u00fcrde mit dem Pfad beziehungsweise mit der Webanwendung etwas nicht stimmen. Also suchte ich bei <code data-start=\"2958\" data-end=\"2968\">PathBase<\/code>, MVC-Routing, Routing-Patterns und der Frage, ob beim Aufbau der URL oder bei der Pfadaufl\u00f6sung etwas falsch interpretiert wird. Alles durchaus plausible Kandidaten.<\/p>\n<p dir=\"auto\" data-start=\"3136\" data-end=\"3164\">Nur war keiner davon schuld.<\/p>\n<p dir=\"auto\" data-start=\"3166\" data-end=\"3340\">Vor dem Wert von <code data-start=\"3183\" data-end=\"3198\">BaseDirectory<\/code> befand sich ein <strong data-start=\"3215\" data-end=\"3241\">unsichtbarer Tabulator<\/strong>. Ein einziges Zeichen reichte aus, damit das angegebene Verzeichnis schlicht nicht gefunden wurde.<\/p>\n<p dir=\"auto\" data-start=\"3342\" data-end=\"3541\">Ich hatte also \u00fcber Routing, Pfade und Framework-Verhalten nachgedacht, w\u00e4hrend sich ganz vorne in der Zeichenkette ein kleiner unsichtbarer Tab versteckte. Die L\u00f6sung war entsprechend unspektakul\u00e4r:<\/p>\n<p dir=\"auto\" data-start=\"3543\" data-end=\"3551\"><code data-start=\"3543\" data-end=\"3551\">Trim()<\/code><\/p>\n<p dir=\"auto\" data-start=\"3553\" data-end=\"3622\">Und pl\u00f6tzlich war das vermeintlich komplizierte Problem verschwunden.<\/p>\n<p dir=\"auto\" data-start=\"3624\" data-end=\"3871\">Genau solche Fehler sind im Nachhinein immer die besten. Man sucht gedanklich schon tief im Framework, \u00fcberlegt sich komplizierte Zusammenh\u00e4nge und fragt sich, welches Verhalten man \u00fcbersehen hat. Und am Ende sagt einem der Computer praktisch nur:<\/p>\n<p dir=\"auto\" data-start=\"3873\" data-end=\"3892\"><strong data-start=\"3873\" data-end=\"3892\">Da war ein Tab.<\/strong><\/p>\n<p dir=\"auto\" data-start=\"3894\" data-end=\"4135\">Am sp\u00e4teren Abend zeigte sich bereits noch ein weiteres Thema mit einem dynamisch erzeugten Device und der Nummer <code data-start=\"4008\" data-end=\"4015\">65535<\/code>. Das Problem war erkannt und grunds\u00e4tzlich nachvollziehbar, aber nichts, was noch am selben Abend gel\u00f6st werden musste.<\/p>\n<p dir=\"auto\" data-start=\"4137\" data-end=\"4172\"><strong data-start=\"4137\" data-end=\"4172\">Das ist ein Problem f\u00fcr morgen.<\/strong><\/p>\n<p dir=\"auto\" data-start=\"4174\" data-end=\"4372\">Nach einem ziemlich chaotischen Start waren damit zwei interessante Probleme gekl\u00e4rt, ein weiteres f\u00fcr den n\u00e4chsten Tag identifiziert und nebenbei noch etwas \u00fcber die eigene Software gelernt worden.<\/p>\n<p dir=\"auto\" data-start=\"4374\" data-end=\"4408\">Eigentlich ein ziemlich guter Tag.<\/p>\n<h3 dir=\"auto\" data-section-id=\"10syapy\" data-start=\"4410\" data-end=\"4423\"><span role=\"text\"><strong data-start=\"4414\" data-end=\"4423\">Fazit<\/strong><\/span><\/h3>\n<p dir=\"auto\" data-start=\"4425\" data-end=\"4663\">Nicht jeder erfolgreiche Arbeitstag f\u00fchlt sich von Anfang an erfolgreich an. Manchmal beginnt er mit mehreren Baustellen gleichzeitig, einer Fernwartung in Zeitlupe und dem Gef\u00fchl, dass heute alles etwas komplizierter sein muss als n\u00f6tig.<\/p>\n<p dir=\"auto\" data-start=\"4665\" data-end=\"4843\">Dann findet man einen Architekturfehler, der bisher nie sichtbar war, sucht anschliessend einen komplizierten Routingfehler und entdeckt stattdessen einen unsichtbaren Tabulator.<\/p>\n<p dir=\"auto\" data-start=\"4845\" data-end=\"4896\">Und irgendwann sitzt man im <a href=\"https:\/\/www.sudpol.ch\/gastronomie\/buvette\" target=\"_blank\" rel=\"noopener\"><strong>Buvette S\u00fcdpol<\/strong><\/a> und stellt fest:<\/p>\n<p dir=\"auto\" data-start=\"4898\" data-end=\"4999\"><strong data-start=\"4898\" data-end=\"4999\">Zwei Probleme gel\u00f6st, eines f\u00fcr morgen gefunden und trotzdem noch rechtzeitig Feierabend gemacht.<\/strong><\/p>\n<p dir=\"auto\" data-start=\"5001\" data-end=\"5023\">Kann man so lassen. \ud83d\ude04<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Geschichte dahinter Manche Arbeitstage beginnen so, als h\u00e4tten sich  [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":483,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[13,18],"tags":[],"class_list":["post-481","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-comics","category-technikwelt"],"_links":{"self":[{"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/posts\/481","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/comments?post=481"}],"version-history":[{"count":4,"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/posts\/481\/revisions"}],"predecessor-version":[{"id":487,"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/posts\/481\/revisions\/487"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/media\/483"}],"wp:attachment":[{"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/media?parent=481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/categories?post=481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.donaldswelt.ch\/index.php\/wp-json\/wp\/v2\/tags?post=481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}