Aufgabe 04-2a - Der Wettlauf
Lernziele
Abschnitt betitelt „Lernziele“- Du erkennst Race Conditions und reproduzierst sie gezielt.
- Du sicherst sie mit In-Flight-Sperre, Abbruch oder latest wins ab.
- Du erklärst, warum solche Fehler nur “manchmal” auftreten, und vergleichst die Abwehrstrategien.
Ausgangslage
Abschnitt betitelt „Ausgangslage“Ein Gast, der zweimal bestellt, weil das Essen nicht kommt, ist im Lokal ärgerlich. Bei einem Bankkonto ist er ein Problem: Zwei Abhebungen, die beide dieselben 100 Euro sehen, ziehen gemeinsam 160 Euro ab.
Du baust zwei Race Conditions absichtlich ein, machst sie zuverlässig sichtbar und entschärfst sie: das Doppelklick-Desaster und die überholte Suchantwort (siehe Kapitel Nebenläufigkeit II: Koordination, Einheit 4.2). Beide Fehler gibt es in echten Anwendungen, und beide treten beim naiven Testen fast nie auf. Alles landet in race.ts. Beide Szenarien bleiben umschaltbar kaputt und repariert: const FIXED = false zeigt den Fehler, const FIXED = true die Abwehr.
Allgemein
Abschnitt betitelt „Allgemein“Projektordner anlegen siehe https://qiz.at/projektordner
- Lies vorher kurz https://qiz.at/assignmentsabgabe durch.
- Nur vollständige Abgaben (siehe https://qiz.at/rules) können positiv bewertet werden.
- Abgabe- und Testdetails siehe https://qiz.at/assignmentsabgabe
- Die Übung liegt als Unterordner
uebung-04-2ain deinem Jahres-RepositorySJ26_27_4AHITM_SEW_<Benutzername>_exercises, eingerichtet wie in Aufgabe 03-2a. Die Logs beider Zustände (FIXEDauffalseund auftrue) und die schriftlichen Erklärungen stehen als Kommentar inrace.ts. Du arbeitest allein.
Wesentlich_überwiegend
Abschnitt betitelt „Wesentlich_überwiegend“Aufgabe
Abschnitt betitelt „Aufgabe“- Simulier ein Konto mit
balance(Startwert100) und einer Methodeasync withdraw(amount). Eine Abhebung läuft in drei Schritten: Saldo lesen und prüfen, ob er reicht (sonst ablehnen),sleep(100)als Verarbeitungszeit, dann den Betrag abziehen. Es gilt:balancedarf niemals negativ werden. - Ruf
withdraw(80)zweimal ohneawaitdazwischen auf (der Doppelklick) und warte dann auf beide. Notiere den Endsaldo und was er hätte sein müssen. - Erklär schriftlich Zeile für Zeile: Wer liest wann welchen Saldo? Warum hilft die Deckungsprüfung nicht?
- Behebe das Problem mit einem In-Flight-Flag: Solange eine Abhebung läuft, wird eine weitere abgewiesen. Weise nach, dass derselbe Doppelaufruf jetzt das richtige Ergebnis liefert und der abgewiesene Aufruf im Log sichtbar ist.
Tipp: Der Kern ist die Lücke zwischen Lesen und Schreiben. Setz das Flag vor die Lücke und gib es in einem
finallywieder frei, sonst bleibt das Konto nach einem Fehler gesperrt.
Bewertungskriterien
Abschnitt betitelt „Bewertungskriterien“Vollständig, wenn:
- der Fehler mit
FIXED = falsereproduzierbar ist (negativer Endsaldo) und der Soll-Wert notiert ist. - die Erklärung zeigt, dass beide Aufrufe denselben Saldo lesen, bevor einer schreibt.
- mit
FIXED = truegenau eine Abhebung gelingt und die zweite abgewiesen wird.
Wie unter Allgemein.
Wesentlich_vollständig
Abschnitt betitelt „Wesentlich_vollständig“Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.
Aufgabe
Abschnitt betitelt „Aufgabe“Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieser Datei (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):
- Simulier
search(term): braucht 100 bis 1500 Millisekunden und liefert eine Ergebnisliste mit dem Suchbegriff. - Feuer drei Suchen kurz hintereinander ab (“H”, “Ha”, “Hau”) und schreib jedes Ergebnis bei Ankunft in eine Variable
displayed. Reproduzier den Fehler: Am Ende steht ein altes Ergebnis indisplayed. - Behebe es mit latest wins: Ein Anfragezähler sorgt dafür, dass nur die Antwort der jüngsten Anfrage übernommen wird. Weise nach, dass jetzt immer das Ergebnis zu “Hau” gewinnt.
Tipp: Zufällige Laufzeiten machen den Fehler unzuverlässig. Für einen sicheren Nachweis gib die Laufzeiten fest vor, die erste Suche am langsamsten.
Bewertungskriterien
Abschnitt betitelt „Bewertungskriterien“Vollständig, wenn:
- der Fehler mit
FIXED = falsezuverlässig reproduziert ist. - mit
FIXED = trueimmer das Ergebnis zu “Hau” angezeigt wird und verworfene Antworten im Log stehen.
Wie unter Allgemein.
PlusPlus Aufgabe
Abschnitt betitelt „PlusPlus Aufgabe“Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.
Aufgabe
Abschnitt betitelt „Aufgabe“Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieser Datei (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):
- Löse die Suchbox ein zweites Mal mit
AbortController: Jede neue Suche bricht die vorige wirklich ab. Deine simulierte Suche muss dafür einsignalannehmen und beiabortihren Timer beenden. - Vergleich beide Lösungen in drei Sätzen: Ressourcen, Aufwand, wann welche?
- Erklär in drei Sätzen, warum diese Fehlerklasse beim Entwicklertest fast nie auftritt und im Betrieb doch, und was das für das Testen bedeutet.
Tipp: Ein abgebrochener Vorgang scheitert mit einem Fehler, dessen
name"AbortError"ist. Diesen Fall fängst du ab, alle anderen Fehler wirfst du weiter.
Bewertungskriterien
Abschnitt betitelt „Bewertungskriterien“Vollständig, wenn:
- nur die letzte Suche fertig wird und die abgebrochenen im Log stehen.
- der Vergleich Ressourcen und Aufwand stichhaltig gegenüberstellt.
- die Erklärung Timing, Last und langsame Verbindungen nennt und eine Folgerung für das Testen zieht.
Wie unter Allgemein.
MandalorianPlus Aufgabe
Abschnitt betitelt „MandalorianPlus Aufgabe“Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.
Aufgabe
Abschnitt betitelt „Aufgabe“Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieser Datei (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):
- Bau die zweite Abwehrstrategie für das Konto: eine Warteschlange, in der jede Abhebung erst startet, wenn die vorige fertig ist. Teste sie mit drei Aufrufen (30, 30, 80).
- Beurteile, welche der beiden Strategien (Sperre oder Warteschlange) für einen Doppelklick passt und welche für zwei gewollte Abhebungen, und begründe es mit dem Verhalten für den Benutzer.
- Nenn zwei Stellen in Apps, die du täglich benutzt, an denen eines der Muster dieser Aufgabe arbeiten muss, und ordne jeder das passende Muster zu.
Tipp: Eine Warteschlange lässt sich mit einer Promise-Kette bauen: Jede neue Abhebung hängt sich mit
thenan das Promise der vorigen.
Bewertungskriterien
Abschnitt betitelt „Bewertungskriterien“Vollständig, wenn:
- die Warteschlange alle Abhebungen nacheinander ausführt und die nicht gedeckte ablehnt.
- die Beurteilung Sperre und Warteschlange dem passenden Fall zuordnet und begründet.
- beide Beispiele aus dem Alltag einem Muster richtig zugeordnet sind.
Wie unter Allgemein.
Wissenscheck
Abschnitt betitelt „Wissenscheck“- Was genau ist die “Lücke”, in der die Doppelklick-Race-Condition entsteht?
- Worin unterscheiden sich In-Flight-Sperre und Warteschlange im Verhalten für den Benutzer?
- Warum reicht es nicht, den Button nur optisch zu deaktivieren?
- Wie funktioniert latest wins mit einem Anfragezähler?
- Was leistet
AbortControllergegenüber dem bloßen Ignorieren alter Antworten?
Zeit dafür
Abschnitt betitelt „Zeit dafür“Durchschnittlich bis Wesentlich_vollständig: ca. 100 min
Autoren
Abschnitt betitelt „Autoren“- Oliver Maurhart (MAO)
- Michael Gabriel (GAM)
CC-BY-SA