Point to snapshot versions
[policy/models.git] / models-interactions / model-actors / actorServiceProvider / src / main / java / org / onap / policy / controlloop / actorserviceprovider / controlloop / ControlLoopEventContext.java
index 1c37a8e..f7b58c1 100644 (file)
@@ -116,6 +116,14 @@ public class ControlLoopEventContext implements Serializable {
         properties.put(name, value);
     }
 
+    /**
+     * Removes a property.
+     * @param name property name
+     */
+    public void removeProperty(String name) {
+        properties.remove(name);
+    }
+
     /**
      * Obtains the given property.
      *
@@ -130,15 +138,27 @@ public class ControlLoopEventContext implements Serializable {
             return null;
         }
 
-        CompletableFuture<OperationOutcome> future = retrievers.get(name);
-        if (future != null) {
-            return future;
-        }
+        /*
+         * Return any existing future, if it wasn't canceled. Otherwise, start a new
+         * request.
+         */
 
-        future = params.start();
+        // @formatter:off
+        CompletableFuture<OperationOutcome> oldFuture =
+            retrievers.computeIfPresent(name, (key, future) -> future.isCancelled() ? null : future);
+        // @formatter:on
 
-        CompletableFuture<OperationOutcome> oldFuture = retrievers.putIfAbsent(name, future);
         if (oldFuture != null) {
+            return oldFuture;
+        }
+
+        /*
+         * Note: must NOT invoke params.start() within retrievers.compute(), as start()
+         * may invoke obtain() which would cause a recursive update to the retrievers map.
+         */
+        CompletableFuture<OperationOutcome> future = params.start();
+
+        if ((oldFuture = retrievers.putIfAbsent(name, future)) != null) {
             future.cancel(false);
             return oldFuture;
         }