@Override public void handleClusterView(boolean mergeView, int newViewId) { synchronized (viewHandlingLock) { // check to ensure this is not an older view if (newViewId <= viewId) { log.tracef("Ignoring old cluster view notification: %s", newViewId); return; } boolean becameCoordinator = !isCoordinator && transport.isCoordinator(); isCoordinator = transport.isCoordinator(); if (trace) { log.tracef( "Received new cluster view: %d, isCoordinator = %s, becameCoordinator = %s", (Object) newViewId, isCoordinator, becameCoordinator); } mustRecoverClusterStatus |= mergeView || becameCoordinator; if (!isCoordinator) return; if (mustRecoverClusterStatus) { // Clean up leftover cache status information from the last time we were coordinator. // E.g. if the local node was coordinator, started a rebalance, and then lost coordinator // status because of a merge, the existing cache statuses may have a rebalance in progress. cacheStatusMap.clear(); try { recoverClusterStatus(newViewId, mergeView, transport.getMembers()); mustRecoverClusterStatus = false; } catch (InterruptedException e) { log.tracef("Cluster state recovery interrupted because the coordinator is shutting down"); // the CTMI has already stopped, no need to update the view id or notify waiters return; } catch (SuspectException e) { // We will retry when we receive the new view and then we'll reset the // mustRecoverClusterStatus flag return; } catch (Exception e) { if (!isShuttingDown) { log.failedToRecoverClusterState(e); } else { log.tracef("Cluster state recovery failed because the coordinator is shutting down"); } } } // update the view id last, so join requests from other nodes wait until we recovered existing // members' info synchronized (viewUpdateLock) { viewId = newViewId; viewUpdateLock.notifyAll(); } } if (!mustRecoverClusterStatus) { try { updateCacheMembers(transport.getMembers()); } catch (Exception e) { log.errorUpdatingMembersList(e); } } }
@Override public void handleClusterView(boolean mergeView, int newViewId) { synchronized (viewHandlingLock) { // check to ensure this is not an older view if (newViewId <= viewId) { log.tracef("Ignoring old cluster view notification: %s", newViewId); return; } boolean becameCoordinator = !isCoordinator && transport.isCoordinator(); isCoordinator = transport.isCoordinator(); log.tracef( "Received new cluster view: %s, isCoordinator = %s, becameCoordinator = %s", newViewId, isCoordinator, becameCoordinator); if (!isCoordinator) return; if (mergeView || becameCoordinator) { try { recoverClusterStatus(newViewId, mergeView, transport.getMembers()); } catch (InterruptedException e) { log.tracef("Cluster state recovery interrupted because the coordinator is shutting down"); // the CTMI has already stopped, no need to update the view id or notify waiters return; } catch (Exception e) { // TODO Retry? log.failedToRecoverClusterState(e); } } else { try { updateCacheMembers(transport.getMembers()); } catch (Exception e) { log.errorUpdatingMembersList(e); } } // update the view id last, so join requests from other nodes wait until we recovered existing // members' info synchronized (viewUpdateLock) { viewId = newViewId; viewUpdateLock.notifyAll(); } } }