/** * Called by join(). Installs the view returned by calling Coord.handleJoin() and becomes * coordinator. */ private boolean installView(View new_view) { Vector mems = new_view.getMembers(); if (log.isDebugEnabled()) log.debug("new_view=" + new_view); if (gms.local_addr == null || mems == null || !mems.contains(gms.local_addr)) { if (log.isErrorEnabled()) log.error( "I (" + gms.local_addr + ") am not member of " + mems + ", will not install view"); return false; } gms.installView(new_view); gms.becomeParticipant(); gms.passUp(new Event(Event.BECOME_SERVER)); gms.passDown(new Event(Event.BECOME_SERVER)); return true; }
/** * GemStoneAddition - new protocol to allow a member to assume the role of coordinator in a system * that has lost all eligible coordinators * * @param mbr the address of this stack * @param failedCoordinator (optional) the address of the coordinator that held the view * @return true if able to become coordinator, false if not */ boolean becomeGroupCoordinator(Address mbr, Address failedCoordinator) { int sentRequests = 0; Digest initial_digest; ViewId view_id; Vector mbrs; Vector imbrs; synchronized (initial_mbrs) { imbrs = (Vector) initial_mbrs.clone(); } // get the current view from one of the members and then // form a new group GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.GET_VIEW); for (int i = 0; i < imbrs.size(); i++) { PingRsp rsp = (PingRsp) imbrs.get(i); Message getView = new Message(); getView.setDest(rsp.getAddress()); getView.putHeader(GMS.name, hdr); gms.passDown(new Event(Event.MSG, getView)); } // wait up to ack-collection-time for responses sentRequests = imbrs.size(); long endTime = System.currentTimeMillis() + gms.view_ack_collection_timeout; while (true) { synchronized (this.getViewLock) { long timeLeft = endTime - System.currentTimeMillis(); if (this.getViewResponses >= sentRequests || timeLeft <= 0) { break; } try { this.getViewLock.wait(timeLeft); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw gms.stack.gfBasicFunctions.getSystemConnectException( ExternalStrings.ClientGmsImpl_INTERRUPTED_WHILE_BECOMING_COORDINATOR_OF_EXISTING_GROUP .toLocalizedString()); } } } if (this.getViewResponse == null) { throw gms.stack.gfBasicFunctions.getSystemConnectException( ExternalStrings .ClientGmsImpl_UNABLE_TO_BECOME_COORDINATOR_OF_EXISTING_GROUP_BECAUSE_NO_VIEW_RESPONSES_WERE_RECEIVED .toLocalizedString()); } View theView = this.getViewResponse.getView(); Address theCreator = theView.getCreator(); if (theCreator != null && theCreator.preferredForCoordinator()) { if (failedCoordinator == null && theView.containsMember(theCreator)) { // locator was shut down and restarted. Other members reported no coordinator // but now there is one, so two eligible coordinators are being started // simultaneously. Return false to allow the other one to win // log.getLogWriterI18n().info(JGroupsStrings.ONE_ARG, "DEBUG: failedCoordinator is // null and view creator is " // + theCreator); return false; } if (failedCoordinator != null && !theCreator.equals(failedCoordinator)) { // the locator or its machine failed and this is a new locator starting // up. Another locator has already installed itself as the coordinator, // so return false to let it win // log.getLogWriterI18n().info(JGroupsStrings.ONE_ARG, "DEBUG: failedCoordinator is // " + failedCoordinator + " and view creator is " // + theCreator); return false; } } mbrs = theView.getMembers(); mbrs.add( mbr); // add myself in (was .add(0, mbr) prior to 2013 cedar release but this caused elder // init problems with colocated secure locators) // create the initial digest. it will be filled in with gossip soon enough initial_digest = this.getViewResponse.getDigest(); initial_digest.add( gms.local_addr, 0, 0); // initial seqno mcast by me will be 1 (highest seen +1) gms.setDigest(initial_digest); view_id = new ViewId( mbr, theView.getVid().getId() + 1); // create singleton view with mbr as only member View new_view = new View(view_id, mbrs); gms.installView(new_view); gms.becomeCoordinator(null); // not really necessary - installView() should do it gms.ucastViewChange(new_view); // tell the world gms.passUp(new Event(Event.BECOME_SERVER)); gms.passDown(new Event(Event.BECOME_SERVER)); gms.notifyOfCoordinator(gms.local_addr); log.getLogWriter() .info(ExternalStrings.ClientGmsImpl_RECREATED_DISTRIBUTED_SYSTEM_GROUP_0, gms.view); return true; }