protected List<PingData> findMembers( Promise<JoinRsp> promise, int num_expected_rsps, boolean break_on_coord, ViewId view_id) { num_discovery_requests++; final Responses rsps = new Responses(num_expected_rsps, num_initial_srv_members, break_on_coord, promise); synchronized (ping_responses) { ping_responses.add(rsps); } try { sendDiscoveryRequest(group_addr, promise, view_id); } catch (InterruptedIOException ie) {; } catch (InterruptedException ex) {; } catch (Throwable ex) { if (log.isErrorEnabled()) log.error("failed sending discovery request", ex); } try { return rsps.get(timeout); } catch (Exception e) { return new LinkedList<PingData>(); } finally { synchronized (ping_responses) { ping_responses.remove(rsps); } } }
/** * An event was received from the layer below. Usually the current layer will want to examine the * event type and - depending on its type - perform some computation (e.g. removing headers from a * MSG event type, or updating the internal membership list when receiving a VIEW_CHANGE event). * Finally the event is either a) discarded, or b) an event is sent down the stack using <code> * PassDown</code> or c) the event (or another event) is sent up the stack using <code>PassUp * </code>. * * <p>For the PING protocol, the Up operation does the following things. 1. If the event is a * Event.MSG then PING will inspect the message header. If the header is null, PING simply passes * up the event If the header is PingHeader.GET_MBRS_REQ then the PING protocol will PassDown a * PingRequest message If the header is PingHeader.GET_MBRS_RSP we will add the message to the * initial members vector and wake up any waiting threads. 2. If the event is Event.SET_LOCAL_ADDR * we will simple set the local address of this protocol 3. For all other messages we simple pass * it up to the protocol above * * @param evt - the event that has been sent from the layer below */ @SuppressWarnings("unchecked") public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); PingHeader hdr = (PingHeader) msg.getHeader(this.id); if (hdr == null) return up_prot.up(evt); PingData data = hdr.data; Address logical_addr = data != null ? data.getAddress() : null; if (is_leaving) return null; // prevents merging back a leaving member // (https://issues.jboss.org/browse/JGRP-1336) switch (hdr.type) { case PingHeader.GET_MBRS_REQ: // return Rsp(local_addr, coord) if (group_addr == null || hdr.cluster_name == null) { if (log.isWarnEnabled()) log.warn( "group_addr (" + group_addr + ") or cluster_name of header (" + hdr.cluster_name + ") is null; passing up discovery request from " + msg.getSrc() + ", but this should not" + " be the case"); } else { if (!group_addr.equals(hdr.cluster_name)) { if (log.isWarnEnabled()) log.warn( "discarding discovery request for cluster '" + hdr.cluster_name + "' from " + msg.getSrc() + "; our cluster name is '" + group_addr + "'. " + "Please separate your clusters cleanly."); return null; } } // add physical address and logical name of the discovery sender (if available) to the // cache if (data != null) { if (logical_addr == null) logical_addr = msg.getSrc(); Collection<PhysicalAddress> physical_addrs = data.getPhysicalAddrs(); PhysicalAddress physical_addr = physical_addrs != null && !physical_addrs.isEmpty() ? physical_addrs.iterator().next() : null; if (logical_addr != null && physical_addr != null) down( new Event( Event.SET_PHYSICAL_ADDRESS, new Tuple<Address, PhysicalAddress>(logical_addr, physical_addr))); if (logical_addr != null && data.getLogicalName() != null) UUID.add(logical_addr, data.getLogicalName()); discoveryRequestReceived(msg.getSrc(), data.getLogicalName(), physical_addrs); synchronized (ping_responses) { for (Responses response : ping_responses) { response.addResponse(data, false); } } } if (hdr.view_id != null) { // If the discovery request is merge-triggered, and the ViewId shipped with it // is the same as ours, we don't respond (JGRP-1315). ViewId my_view_id = view != null ? view.getViewId() : null; if (my_view_id != null && my_view_id.equals(hdr.view_id)) return null; boolean send_discovery_rsp = force_sending_discovery_rsps || is_coord || current_coord == null || current_coord.equals(msg.getSrc()); if (!send_discovery_rsp) { if (log.isTraceEnabled()) log.trace( local_addr + ": suppressing merge response as I'm not a coordinator and the " + "discovery request was not sent by a coordinator"); return null; } } if (isMergeRunning()) { if (log.isTraceEnabled()) log.trace( local_addr + ": suppressing merge response as a merge is already in progress"); return null; } List<PhysicalAddress> physical_addrs = hdr.view_id != null ? null : Arrays.asList( (PhysicalAddress) down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr))); sendDiscoveryResponse( local_addr, physical_addrs, is_server, hdr.view_id != null, UUID.get(local_addr), msg.getSrc()); return null; case PingHeader.GET_MBRS_RSP: // add response to vector and notify waiting thread // add physical address (if available) to transport's cache if (data != null) { Address response_sender = msg.getSrc(); if (logical_addr == null) logical_addr = msg.getSrc(); Collection<PhysicalAddress> addrs = data.getPhysicalAddrs(); PhysicalAddress physical_addr = addrs != null && !addrs.isEmpty() ? addrs.iterator().next() : null; if (logical_addr != null && physical_addr != null) down( new Event( Event.SET_PHYSICAL_ADDRESS, new Tuple<Address, PhysicalAddress>(logical_addr, physical_addr))); if (logical_addr != null && data.getLogicalName() != null) UUID.add(logical_addr, data.getLogicalName()); if (log.isTraceEnabled()) log.trace( local_addr + ": received GET_MBRS_RSP from " + response_sender + ": " + data); boolean overwrite = logical_addr != null && logical_addr.equals(response_sender); synchronized (ping_responses) { for (Responses response : ping_responses) { response.addResponse(data, overwrite); } } } return null; default: if (log.isWarnEnabled()) log.warn("got PING header with unknown type (" + hdr.type + ')'); return null; } case Event.GET_PHYSICAL_ADDRESS: try { sendDiscoveryRequest(group_addr, null, null); } catch (InterruptedIOException ie) { if (log.isWarnEnabled()) { log.warn("Discovery request for cluster " + group_addr + " interrupted"); } Thread.currentThread().interrupt(); } catch (Exception ex) { if (log.isErrorEnabled()) log.error("failed sending discovery request", ex); } return null; case Event.FIND_INITIAL_MBRS: // sent by transport return findInitialMembers(null); } return up_prot.up(evt); }