Wir haben eine asynchrone Aufgabe, die eine potenziell lang laufende Berechnung für ein Objekt ausführt. Das Ergebnis wird dann im Objekt zwischengespeichert. Um mehrere Aufgaben zu wiederholen, die gleiche Arbeit zu vermeiden, haben wir mit einem Atom SQL Update Sperren:Simulieren von Wettlaufbedingungen in RSpec-Komponententests
UPDATE objects SET locked = 1 WHERE id = 1234 AND locked = 0
Die Verriegelung nur für die asynchrone Aufgabe. Das Objekt selbst kann vom Benutzer noch aktualisiert werden. Wenn dies geschieht, sollte eine nicht abgeschlossene Aufgabe für eine alte Version des Objekts die Ergebnisse verwerfen, da sie wahrscheinlich nicht mehr aktuell sind. Dies ist auch recht einfach mit einem Atom SQL-Update zu tun:
UPDATE objects SET results = '...' WHERE id = 1234 AND version = 1
Wenn das Objekt aktualisiert wurde, wird seine Version nicht überein, und so werden die Ergebnisse verworfen werden.
Diese beiden atomaren Updates sollten alle möglichen Rennbedingungen behandeln. Die Frage ist, wie das in Unit-Tests zu überprüfen ist.
Der erste Semaphor ist einfach zu testen, da es nur darum geht, zwei verschiedene Tests mit den zwei möglichen Szenarien einzurichten: (1) wo das Objekt gesperrt ist und (2) wo das Objekt nicht gesperrt ist. (Wir müssen die Atomizität der SQL-Abfrage nicht testen, da dies in der Verantwortung des Datenbankherstellers liegt.)
Wie testet man den zweiten Semaphor? Das Objekt muss einige Zeit nach dem ersten Semaphor, aber vor dem zweiten von einem Dritten geändert werden. Dies würde eine Ausführungspause erfordern, so dass die Aktualisierung zuverlässig und konsistent durchgeführt werden kann, aber ich kenne keine Unterstützung für das Einfügen von Haltepunkten mit RSpec. Gibt es eine Möglichkeit, dies zu tun? Oder gibt es eine andere Technik, die ich übersehen habe, um solche Rassenbedingungen zu simulieren?
A-ha. Das würde es tun.Anstatt einen expliziten Hook hinzuzufügen, kann ich einfach 'alias_method_chain' verwenden, um die Funktionalität einer Methode zu erweitern, die sowieso zwischen den beiden Semaphoren aufgerufen werden muss - die lang andauernde Aufgabe. – Ian
Ian, Das würde es tun. –
+1 für die Verwendung von parasitischen Wespenlarven in Ihrem Gleichnis. – aronchick