Skip to content

Commit

Permalink
[mqtt][HA] ConcurrentHashMap to avoid ConcurrentModificationException (
Browse files Browse the repository at this point in the history
…openhab#8239)

* [mqtt][homeassistant] Use ConcurrentHashMap to avoid ConcurrentModificationException

Signed-off-by: Aitor Iturrioz <[email protected]>
  • Loading branch information
bodiroga authored and andrewfg committed Aug 31, 2020
1 parent f2155cc commit 6743e26
Showing 1 changed file with 11 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -65,7 +65,7 @@ public class HomeAssistantDiscovery extends AbstractMQTTDiscovery {
private final Logger logger = LoggerFactory.getLogger(HomeAssistantDiscovery.class);
protected final Map<String, Set<HaID>> componentsPerThingID = new TreeMap<>();
protected final Map<String, ThingUID> thingIDPerTopic = new TreeMap<>();
protected final Map<String, DiscoveryResult> results = new TreeMap<>();
protected final Map<String, DiscoveryResult> results = new ConcurrentHashMap<>();

private @Nullable ScheduledFuture<?> future;
private final Gson gson;
Expand Down Expand Up @@ -165,7 +165,7 @@ public void receivedMessage(ThingUID connectionBridge, MqttBrokerConnection conn
thingIDPerTopic.put(topic, thingUID);

// We need to keep track of already found component topics for a specific thing
Set<HaID> components = componentsPerThingID.computeIfAbsent(thingID, key -> new HashSet<>());
Set<HaID> components = componentsPerThingID.computeIfAbsent(thingID, key -> ConcurrentHashMap.newKeySet());
components.add(haID);

final String componentNames = components.stream().map(id -> id.component)
Expand All @@ -178,23 +178,19 @@ public void receivedMessage(ThingUID connectionBridge, MqttBrokerConnection conn
properties = handlerConfig.appendToProperties(properties);
properties = config.appendToProperties(properties);

synchronized (results) {
// Because we need the new properties map with the updated "components" list
results.put(thingUID.getAsString(),
DiscoveryResultBuilder.create(thingUID).withProperties(properties)
.withRepresentationProperty("objectid").withBridge(connectionBridge)
.withLabel(config.getThingName() + " (" + componentNames + ")").build());
}
// Because we need the new properties map with the updated "components" list
results.put(thingUID.getAsString(),
DiscoveryResultBuilder.create(thingUID).withProperties(properties).withRepresentationProperty(thingID)
.withBridge(connectionBridge).withLabel(config.getThingName() + " (" + componentNames + ")")
.build());
}

protected void publishResults() {
Collection<DiscoveryResult> localResults;

synchronized (results) {
localResults = new ArrayList<>(results.values());
results.clear();
componentsPerThingID.clear();
}
localResults = new ArrayList<>(results.values());
results.clear();
componentsPerThingID.clear();
for (DiscoveryResult result : localResults) {
final ThingTypeUID typeID = result.getThingTypeUID();
ThingType type = typeProvider.derive(typeID, MqttBindingConstants.HOMEASSISTANT_MQTT_THING).build();
Expand Down

0 comments on commit 6743e26

Please sign in to comment.