Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
Description
this WAN code in LocatorMembershipListenerImpl$DistributeLocatorsRunnable.run:
Set<LocatorJoinMessage> joinMessages = entry.getValue(); for (LocatorJoinMessage locatorJoinMessage : joinMessages) { if (retryMessage(targetLocator, locatorJoinMessage, attempt)) { joinMessages.remove(locatorJoinMessage); } else {
modifies the joinMessages set as it is iterating over the set, resulting in a ConcurrentModificationException.
This bug will cause (inter-site) notification of locators (of the presence of a new locator) to fail early if retry is necessary. If we have to retry notifying any locator, and we succeed, we’ll throw the ConcurrentModificationException and stop trying to notify any of the other locators. See the Discovery For Multi-Site Systems section of the Overview of Multi-Site Caching documentation for an overview of the locator's role in WAN.
Here is a scratch file that illustrates the issue, throwing ConcurrentModificationException:
import java.util.HashSet; import java.util.Set; class Scratch { public static void main(String[] args) { final Set<String> joinMessages = new HashSet<>(); joinMessages.add("one"); joinMessages.add("two"); for( final String entry:joinMessages ) { if (entry.equals("one")) joinMessages.remove(entry); } } }
From looking at the Geode code, joinMessages is not used outside the loop so there is no need to modify it at all—I think we can simply remove this line:
joinMessages.remove(locatorJoinMessage);