@Override public boolean setMembershipManager(MembershipManager mgr) { if (services == null || services.isStopped()) { logger.info("Peer locator is connecting to local membership services"); services = ((GMSMembershipManager) mgr).getServices(); localAddress = services.getMessenger().getMemberID(); services.setLocator(this); NetView newView = services.getJoinLeave().getView(); if (newView != null) { this.view = newView; } return true; } return false; }
@Override public Object processRequest(Object request) throws IOException { Object response = null; if (logger.isDebugEnabled()) { logger.debug("Peer locator processing {}", request); } if (localAddress == null && services != null) { localAddress = services.getMessenger().getMemberID(); } if (request instanceof GetViewRequest) { if (view != null) { response = new GetViewResponse(view); } } else if (request instanceof FindCoordinatorRequest) { FindCoordinatorRequest findRequest = (FindCoordinatorRequest) request; if (findRequest.getMemberID() != null) { InternalDistributedMember coord = null; // at this level we want to return the coordinator known to membership services, // which may be more up-to-date than the one known by the membership manager if (view == null) { findServices(); } boolean fromView = false; int viewId = -1; NetView v = this.view; if (v != null) { // if the ID of the requester matches an entry in the membership view then remove // that entry - it's obviously an old member since the ID has been reused InternalDistributedMember rid = findRequest.getMemberID(); for (InternalDistributedMember id : v.getMembers()) { if (rid.compareTo(id, false) == 0) { NetView newView = new NetView(v, v.getViewId()); newView.remove(id); v = newView; break; } } viewId = v.getViewId(); if (viewId > findRequest.getLastViewId()) { // ignore the requests rejectedCoordinators if the view has changed coord = v.getCoordinator(Collections.<InternalDistributedMember>emptyList()); } else { coord = v.getCoordinator(findRequest.getRejectedCoordinators()); } logger.debug("Peer locator: coordinator from view is {}", coord); fromView = true; } if (coord == null) { // find the "oldest" registrant Collection<InternalDistributedMember> rejections = findRequest.getRejectedCoordinators(); if (rejections == null) { rejections = Collections.emptyList(); } synchronized (registrants) { registrants.add(findRequest.getMemberID()); if (services != null) { coord = services.getJoinLeave().getMemberID(); } for (InternalDistributedMember mbr : registrants) { if (mbr != coord && (coord == null || mbr.compareTo(coord) < 0)) { if (!rejections.contains(mbr) && (mbr.getNetMember().preferredForCoordinator() || !mbr.getNetMember().splitBrainEnabled())) { coord = mbr; } } } logger.debug("Peer locator: coordinator from registrations is {}", coord); } } synchronized (registrants) { response = new FindCoordinatorResponse( coord, localAddress, fromView, view, new HashSet<InternalDistributedMember>(registrants), this.networkPartitionDetectionEnabled, this.usePreferredCoordinators); } } } if (logger.isDebugEnabled()) { logger.debug("Peer locator returning {}", response); } return response; }