This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 15c749a9b34f2d0eb932b1890c673849713657d7
Author: Alex Heneveld <g...@alex.heneveld.org>
AuthorDate: Tue Jul 30 10:50:18 2024 +0100

    defend against ConcurrentModError when doing attrWhenReady waits
---
 .../core/sensor/DependentConfiguration.java        | 27 ++++++++++++++--------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git 
a/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java
 
b/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java
index c95cf7e68e..9611362a0b 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java
@@ -40,6 +40,7 @@ import org.apache.brooklyn.util.JavaGroovyEquivalents;
 import org.apache.brooklyn.util.collections.CollectionFunctionals;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.core.task.*;
 import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
@@ -364,14 +365,16 @@ public class DependentConfiguration {
 
                 Map<Integer,Duration> customTimeouts = MutableMap.of();
                 BiConsumer<Integer,Object> checkValueAtIndex = (index, val) -> 
{
-                    Pair<AttributeAndSensorCondition<Object>, Duration> 
timeoutIfCondition = timeoutIfTimeoutSensorConditions.get(index);
-                    if (timeoutIfCondition.getLeft().predicate.apply(val)) {
-                        if (!customTimeouts.containsKey(index)) {
-                            // start timer from this point
-                            customTimeouts.put(index, 
timer.getDurationElapsed().add(timeoutIfCondition.getRight()));
+                    synchronized (customTimeouts) {
+                        Pair<AttributeAndSensorCondition<Object>, Duration> 
timeoutIfCondition = timeoutIfTimeoutSensorConditions.get(index);
+                        if (timeoutIfCondition.getLeft().predicate.apply(val)) 
{
+                            if (!customTimeouts.containsKey(index)) {
+                                // start timer from this point
+                                customTimeouts.put(index, 
timer.getDurationElapsed().add(timeoutIfCondition.getRight()));
+                            }
+                        } else {
+                            customTimeouts.remove(index);
                         }
-                    } else {
-                        customTimeouts.remove(index);
                     }
                 };
 
@@ -439,8 +442,14 @@ public class DependentConfiguration {
                         throw new CompoundRuntimeException("Aborted waiting 
for ready value from "+source+" "+sensor.getName(), abortionExceptions);
                     }
 
-                    if (!customTimeouts.isEmpty()) {
-                        for (Map.Entry<Integer, Duration> entry : 
customTimeouts.entrySet()) {
+                    Set<Map.Entry<Integer, Duration>> timeoutsHere = null;
+                    synchronized (customTimeouts) {
+                        if (!customTimeouts.isEmpty()) {
+                            timeoutsHere = 
MutableSet.copyOf(customTimeouts.entrySet());
+                        }
+                    }
+                    if (timeoutsHere!=null) {
+                        for (Map.Entry<Integer, Duration> entry : 
timeoutsHere) {
                             Integer index = entry.getKey();
                             Duration specialTimeout = entry.getValue();
                             Pair<AttributeAndSensorCondition<Object>, 
Duration> timeoutIfCondition = timeoutIfTimeoutSensorConditions.get(index);

Reply via email to