/** Send a message to the address specified in msg.dest */ private void sendUnicastMessage(Message msg) { IpAddress dest; Message copy; Object hdr; Event evt; dest = (IpAddress) msg.getDest(); // guaranteed not to be null if (!(dest instanceof IpAddress)) { Trace.error("TCP.sendUnicastMessage()", "destination address is not of type IpAddress !"); return; } setSourceAddress(msg); /* Don't send if destination is local address. Instead, switch dst and src and put in up_queue */ if (loopback && local_addr != null && dest != null && dest.equals(local_addr)) { copy = msg.copy(); hdr = copy.getHeader(getName()); if (hdr != null && hdr instanceof TcpHeader) copy.removeHeader(getName()); copy.setSrc(local_addr); copy.setDest(local_addr); evt = new Event(Event.MSG, copy); /* Because Protocol.up() is never called by this bottommost layer, we call up() directly in the observer. This allows e.g. PerfObserver to get the time of reception of a message */ if (observer != null) observer.up(evt, up_queue.size()); passUp(evt); return; } if (Trace.trace) Trace.info( "TCP.sendUnicastMessage()", "dest=" + msg.getDest() + ", hdrs:\n" + msg.printObjectHeaders()); try { if (skip_suspected_members) { if (suspected_mbrs.contains(dest)) { if (Trace.trace) Trace.info( "TCP.sendUnicastMessage()", "will not send unicast message to " + dest + " as it is currently suspected"); return; } } ct.send(msg); } catch (SocketException e) { if (members.contains(dest)) { if (!suspected_mbrs.contains(dest)) { suspected_mbrs.add(dest); passUp(new Event(Event.SUSPECT, dest)); } } } }
synchronized void add(Request req) { if (suspended) { if (log.isTraceEnabled()) log.trace(local_addr + ": queue is suspended; request " + req + " is discarded"); return; } start(); try { queue.add(req); history.add(new Date() + ": " + req.toString()); } catch (QueueClosedException e) { if (log.isTraceEnabled()) log.trace("queue is closed; request " + req + " is discarded"); } }
public boolean setMergeId(MergeId expected, MergeId new_value) { merge_lock.lock(); try { boolean match = Util.match(this.merge_id, expected); if (match) { if (new_value != null && merge_id_history.contains(new_value)) return false; else merge_id_history.add(new_value); this.merge_id = new_value; if (this.merge_id != null) { // Clears the view handler queue and discards all JOIN/LEAVE/MERGE requests until after // the MERGE gms.getViewHandler().suspend(); gms.getDownProtocol().down(new Event(Event.SUSPEND_STABLE, 20000)); startMergeKiller(); } } return match; } finally { merge_lock.unlock(); } }
/** * Sets the new view and sends a VIEW_CHANGE event up and down the stack. If the view is a * MergeView (subclass of View), then digest will be non-null and has to be set before installing * the view. */ public void installView(View new_view, Digest digest) { ViewId vid = new_view.getVid(); List<Address> mbrs = new_view.getMembers(); ltime = Math.max( vid.getId(), ltime); // compute the logical time, regardless of whether the view is accepted // Discards view with id lower than or equal to our own. Will be installed without check if it // is the first view if (view != null) { ViewId view_id = view.getViewId(); int rc = vid.compareToIDs(view_id); if (rc <= 0) { if (log.isWarnEnabled() && rc < 0 && log_view_warnings) { // only scream if view is smaller, silently discard same views log.warn( local_addr + ": received view < current view;" + " discarding it (current vid: " + view_id + ", new vid: " + vid + ')'); } return; } } /* Check for self-inclusion: if I'm not part of the new membership, I just discard it. This ensures that messages sent in view V1 are only received by members of V1 */ if (!mbrs.contains(local_addr)) { if (log.isWarnEnabled() && log_view_warnings) log.warn(local_addr + ": not member of view " + new_view.getViewId() + "; discarding it"); return; } if (digest != null) { if (new_view instanceof MergeView) mergeDigest(digest); else setDigest(digest); } if (log.isDebugEnabled()) log.debug(local_addr + ": installing view " + new_view); Event view_event; synchronized (members) { view = new View(new_view.getVid(), new_view.getMembers()); view_event = new Event(Event.VIEW_CHANGE, new_view); // Set the membership. Take into account joining members if (!mbrs.isEmpty()) { members.set(mbrs); tmp_members.set(members); joining.removeAll(mbrs); // remove all members in mbrs from joining // remove all elements from 'leaving' that are not in 'mbrs' leaving.retainAll(mbrs); tmp_members.add(joining); // add members that haven't yet shown up in the membership tmp_members.remove( leaving); // remove members that haven't yet been removed from the membership // add to prev_members for (Address addr : mbrs) { if (!prev_members.contains(addr)) prev_members.add(addr); } } Address coord = determineCoordinator(); if (coord != null && coord.equals(local_addr) && !haveCoordinatorRole()) { becomeCoordinator(); } else { if (haveCoordinatorRole() && !local_addr.equals(coord)) { becomeParticipant(); merge_ack_collector.reset(null); // we don't need this one anymore } } } // - Changed order of passing view up and down (http://jira.jboss.com/jira/browse/JGRP-347) // - Changed it back (bela Sept 4 2007): http://jira.jboss.com/jira/browse/JGRP-564 // - Moved sending up view_event out of the synchronized block (bela Nov 2011) down_prot.down(view_event); // needed e.g. by failure detector or UDP up_prot.up(view_event); List<Address> tmp_mbrs = new_view.getMembers(); ack_collector.retainAll(tmp_mbrs); merge_ack_collector.retainAll(tmp_mbrs); if (new_view instanceof MergeView) merger.forceCancelMerge(); if (stats) { num_views++; prev_views.add(new Tuple<View, Long>(new_view, System.currentTimeMillis())); } }