use of org.wildfly.clustering.group.Node in project wildfly by wildfly.
the class CacheServiceProviderRegistry method membershipChanged.
@Override
public void membershipChanged(List<Node> previousMembers, List<Node> members, final boolean merged) {
if (this.getGroup().isCoordinator()) {
Set<Node> deadNodes = new HashSet<>(previousMembers);
deadNodes.removeAll(members);
Set<Node> newNodes = new HashSet<>(members);
newNodes.removeAll(previousMembers);
if (!deadNodes.isEmpty()) {
try (Batch batch = this.batcher.createBatch()) {
try (CloseableIterator<Map.Entry<T, Set<Node>>> entries = this.cache.entrySet().iterator()) {
while (entries.hasNext()) {
Map.Entry<T, Set<Node>> entry = entries.next();
Set<Node> nodes = entry.getValue();
if (nodes.removeAll(deadNodes)) {
entry.setValue(nodes);
}
}
}
}
}
if (merged) {
// Re-assert services for new members following merge since these may have been lost following split
for (Node node : newNodes) {
try {
Collection<T> services = this.dispatcher.executeOnNode(new GetLocalServicesCommand<>(), node).get();
try (Batch batch = this.batcher.createBatch()) {
services.forEach(service -> this.register(node, service));
}
} catch (Exception e) {
ClusteringServerLogger.ROOT_LOGGER.warn(e.getLocalizedMessage(), e);
}
}
}
}
}
use of org.wildfly.clustering.group.Node in project wildfly by wildfly.
the class CacheRegistry method close.
@Override
public void close() {
this.cache.removeListener(this);
this.shutdown(this.topologyChangeExecutor);
Node node = this.getGroup().getLocalNode();
try (Batch batch = this.batcher.createBatch()) {
// If this remove fails, the entry will be auto-removed on topology change by the new primary owner
this.cache.getAdvancedCache().withFlags(Flag.IGNORE_RETURN_VALUES, Flag.FAIL_SILENTLY).remove(node);
} catch (CacheException e) {
ClusteringLogger.ROOT_LOGGER.warn(e.getLocalizedMessage(), e);
} finally {
// Cleanup any unregistered listeners
this.listeners.values().forEach(executor -> this.shutdown(executor));
this.listeners.clear();
this.closeTask.run();
}
}
use of org.wildfly.clustering.group.Node in project wildfly by wildfly.
the class CacheRegistry method topologyChanged.
@TopologyChanged
public void topologyChanged(TopologyChangedEvent<Node, Map.Entry<K, V>> event) {
if (event.isPre())
return;
ConsistentHash previousHash = event.getConsistentHashAtStart();
List<Address> previousMembers = previousHash.getMembers();
ConsistentHash hash = event.getConsistentHashAtEnd();
List<Address> members = hash.getMembers();
Address localAddress = event.getCache().getCacheManager().getAddress();
// Determine which nodes have left the cache view
Set<Address> addresses = new HashSet<>(previousMembers);
addresses.removeAll(members);
try {
this.topologyChangeExecutor.submit(() -> {
if (!addresses.isEmpty()) {
// We're only interested in the entries for which we are the primary owner
List<Node> nodes = addresses.stream().filter(address -> hash.locatePrimaryOwner(address).equals(localAddress)).map(address -> this.factory.createNode(address)).collect(Collectors.toList());
if (!nodes.isEmpty()) {
Cache<Node, Map.Entry<K, V>> cache = this.cache.getAdvancedCache().withFlags(Flag.FORCE_SYNCHRONOUS);
Map<K, V> removed = new HashMap<>();
try (Batch batch = this.batcher.createBatch()) {
for (Node node : nodes) {
Map.Entry<K, V> old = cache.remove(node);
if (old != null) {
removed.put(old.getKey(), old.getValue());
}
}
} catch (CacheException e) {
ClusteringServerLogger.ROOT_LOGGER.registryPurgeFailed(e, this.cache.getCacheManager().toString(), this.cache.getName(), nodes);
}
// Invoke listeners outside above tx context
if (!removed.isEmpty()) {
this.notifyListeners(Event.Type.CACHE_ENTRY_REMOVED, removed);
}
}
} else {
// This is a merge after cluster split: re-populate the cache registry with lost registry entries
if (!previousMembers.contains(localAddress)) {
// If this node is not a member at merge start, its mapping is lost and needs to be recreated and listeners notified
try {
this.populateRegistry();
// Local cache events do not trigger notifications
this.notifyListeners(Event.Type.CACHE_ENTRY_CREATED, this.entry);
} catch (CacheException e) {
ClusteringServerLogger.ROOT_LOGGER.failedToRestoreLocalRegistryEntry(e, this.cache.getCacheManager().toString(), this.cache.getName());
}
}
}
});
} catch (RejectedExecutionException e) {
// Executor was shutdown
}
}
use of org.wildfly.clustering.group.Node in project wildfly by wildfly.
the class DistributedSingletonService method providersChanged.
@Override
public void providersChanged(Set<Node> nodes) {
Group group = this.registry.getValue().getGroup();
List<Node> candidates = group.getNodes();
candidates.retainAll(nodes);
// Only run election on a single node
if (candidates.isEmpty() || candidates.get(0).equals(group.getLocalNode())) {
// First validate that quorum was met
int size = candidates.size();
boolean quorumMet = size >= this.quorum;
if ((this.quorum > 1) && (size == this.quorum)) {
// Log fragility of singleton availability
ClusteringServerLogger.ROOT_LOGGER.quorumJustReached(this.serviceName.getCanonicalName(), this.quorum);
}
Node elected = quorumMet ? this.electionPolicy.elect(candidates) : null;
try {
if (elected != null) {
ClusteringServerLogger.ROOT_LOGGER.elected(elected.getName(), this.serviceName.getCanonicalName());
// Stop service on every node except elected node
this.dispatcher.executeOnCluster(new StopCommand<>(), elected);
// Start service on elected node
this.dispatcher.executeOnNode(new StartCommand<>(), elected);
} else {
if (quorumMet) {
ClusteringServerLogger.ROOT_LOGGER.noPrimaryElected(this.serviceName.getCanonicalName());
} else {
ClusteringServerLogger.ROOT_LOGGER.quorumNotReached(this.serviceName.getCanonicalName(), this.quorum);
}
// Stop service on every node
this.dispatcher.executeOnCluster(new StopCommand<>());
}
} catch (CommandDispatcherException e) {
throw new IllegalStateException(e);
}
}
}
use of org.wildfly.clustering.group.Node in project wildfly by wildfly.
the class SocketAddressPreferenceTestCase method test.
@Test
public void test() throws UnknownHostException {
InetSocketAddress preferredAddress = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 1);
InetSocketAddress otherAddress1 = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 2);
InetSocketAddress otherAddress2 = new InetSocketAddress(InetAddress.getByName("127.0.0.2"), 1);
Preference preference = new SocketAddressPreference(preferredAddress);
Node preferredNode = mock(Node.class);
Node otherNode1 = mock(Node.class);
Node otherNode2 = mock(Node.class);
when(preferredNode.getSocketAddress()).thenReturn(preferredAddress);
when(otherNode1.getSocketAddress()).thenReturn(otherAddress1);
when(otherNode2.getSocketAddress()).thenReturn(otherAddress2);
assertTrue(preference.preferred(preferredNode));
assertFalse(preference.preferred(otherNode1));
assertFalse(preference.preferred(otherNode2));
}
Aggregations