Race Condition beim Anlegen von dynamischen Objekten
Folgender Code aus dem Testfall de.bsvrz.dav.daf.main.config.dynamicObject.TestDynamicObjectCreation#testCreateDeleteReconnectCompareElements2 liefert aktuell je nach Testumgebung inkonsistente Ergebnisse:
final DynamicObjectType dynamicObjectType = (DynamicObjectType)configuration.getType("typ.applikation");
elements1 = dynamicObjectType.getElements();
final DynamicObject dyn1 = area.createDynamicObject(dynamicObjectType, "objekt.testCreateDeleteReconnectGetElements2", "");
List<SystemObject> elements1b = dynamicObjectType.getElements();
Assert.assertEquals(elements1 + " != " + elements1b, elements1.size() + 1, elements1b.size());
Das Problem, das auftritt ist, dass elements1b
das gerade erzeuge Objekt nicht enthält, obwohl es den passenden Typ besitzt und enthalten sein müsste. Das beobachtete Verhalten ist also aus Anwendersicht nicht logisch.
Grund ist, dass die Methode dynamicObjectType.getElements()
die Objekte eines Typs nicht jedes mal neu abfragt, sondern einen Cache enthält. Über einen Listener-Mechanismus teilt die Konfiguration der Applikation laufend Änderungen über die enthaltenen Elemente mit.
Zeitlich sieht das etwa so aus:
Fehler-Fall:
Applikation Konfiguration
| |
|-Objekt anlegen--------------------->|
| |
| +----------Neues Element in Typ-|
| | |
|<----|---Objekt erfolgreich angelegt-|
| | |
| <async> |
| | |
|<----+ |
| |
Erwarteter Normalfall:
Applikation Konfiguration
| |
|-Objekt anlegen--------------------->|
| |
| +----------Neues Element in Typ-|
| <async> |
|<----+ |
| |
|<--------Objekt erfolgreich angelegt-|
Wenn die Applikation die (asynchron empfangene) "Neues Element in Typ"-Nachricht nicht schnell genug erhält/auswertet, dann kann es also etwas dauern, bis dynamicObjectType.getElements()
wirklich das neue Objekt zurückliefert.
Das Problem scheint erst seit letzter Zeit aufzutreten, vermutlich durch die Performanceverbesserungen in #13 (closed). Der Grund müsste aber noch genauer analysiert werden.
Es ist möglich, dass das Verhalten in der Praxis nur bei Applikationsobjekten auftritt (welche der Testfall benutzt), da diese transient sind und daher sehr schnell angelegt werden können.
Zur Lösung könnte entweder der asynchrone Mechanismus an der Stelle entfernt werden (sofern es dadurch keine Performanceprobleme oder Deadlocks geben kann) oder man könnte das Cache-Verhalten anpassen für den Fall, dass die Applikation weiß, wenn ein Objekt enthalten sein muss, da sie es selbst angelegt hat.