/** * An event is to be sent down the stack. The layer may want to examine its type and perform some * action on it, depending on the event's type. If the event is a message MSG, then the layer may * need to add a header to it (or do nothing at all) before sending it down the stack using <code> * PassDown</code>. In case of a GET_ADDRESS event (which tries to retrieve the stack's address * from one of the bottom layers), the layer may need to send a new response event back up the * stack using <code>up_prot.up()</code>. The PING protocol is interested in several different * down events, Event.FIND_INITIAL_MBRS - sent by the GMS layer and expecting a GET_MBRS_OK * Event.TMP_VIEW and Event.VIEW_CHANGE - a view change event Event.BECOME_SERVER - called after * client has joined and is fully working group member Event.CONNECT, Event.DISCONNECT. */ @SuppressWarnings("unchecked") public Object down(Event evt) { switch (evt.getType()) { case Event.FIND_INITIAL_MBRS: // sent by GMS layer case Event.FIND_ALL_VIEWS: // sends the GET_MBRS_REQ to all members, waits 'timeout' ms or until 'num_initial_members' // have been retrieved long start = System.currentTimeMillis(); boolean find_all_views = evt.getType() == Event.FIND_ALL_VIEWS; Promise<JoinRsp> promise = (Promise<JoinRsp>) evt.getArg(); List<PingData> rsps = find_all_views ? findAllViews(promise) : findInitialMembers(promise); long diff = System.currentTimeMillis() - start; if (log.isTraceEnabled()) log.trace("discovery took " + diff + " ms: responses: " + Util.printPingData(rsps)); return rsps; case Event.TMP_VIEW: case Event.VIEW_CHANGE: List<Address> tmp; view = (View) evt.getArg(); if ((tmp = view.getMembers()) != null) { synchronized (members) { members.clear(); members.addAll(tmp); } } current_coord = !members.isEmpty() ? members.get(0) : null; is_coord = current_coord != null && local_addr != null && current_coord.equals(local_addr); return down_prot.down(evt); case Event.BECOME_SERVER: // called after client has joined and is fully working group member down_prot.down(evt); is_server = true; return null; case Event.SET_LOCAL_ADDRESS: local_addr = (Address) evt.getArg(); return down_prot.down(evt); case Event.CONNECT: case Event.CONNECT_WITH_STATE_TRANSFER: case Event.CONNECT_USE_FLUSH: case Event.CONNECT_WITH_STATE_TRANSFER_USE_FLUSH: is_leaving = false; group_addr = (String) evt.getArg(); Object ret = down_prot.down(evt); handleConnect(); return ret; case Event.DISCONNECT: is_leaving = true; handleDisconnect(); return down_prot.down(evt); default: return down_prot.down(evt); // Pass on to the layer below us } }
public void run() { Event evt; while (evt_thread != null && event_queue != null) { try { evt = (Event) event_queue.remove(); switch (evt.getType()) { case Event.SUSPECT: impl.suspect((Address) evt.getArg()); break; case Event.MERGE: impl.merge((Vector) evt.getArg()); break; default: Trace.error( "GMS.run()", "event handler thread encountered event of type " + Event.type2String(evt.getType()) + ": not handled by me !"); break; } } catch (QueueClosedException closed) { break; } catch (Exception ex) { Trace.warn("GMS.run()", "exception=" + ex); } } }
public Object up(Event evt) { if (evt.getType() == Event.SET_LOCAL_ADDRESS) { localAddress = evt.getArg(); if (discard_dialog != null) discard_dialog.setTitle("Discard dialog (" + localAddress + ")"); } return up_prot.up(evt); }
public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); DaisyHeader hdr = (DaisyHeader) msg.getHeader(getId()); if (hdr == null) break; // 1. forward the message to the next in line if ttl > 0 short ttl = hdr.getTTL(); if (log.isTraceEnabled()) log.trace(local_addr + ": received message from " + msg.getSrc() + " with ttl=" + ttl); if (--ttl > 0) { Message copy = msg.copy(true); copy.setDest(next); copy.putHeader(getId(), new DaisyHeader(ttl)); msgs_forwarded++; if (log.isTraceEnabled()) log.trace(local_addr + ": forwarding message to " + next + " with ttl=" + ttl); down_prot.down(new Event(Event.MSG, copy)); } // 2. Pass up msg.setDest(null); break; } return up_prot.up(evt); }
/** * Fragment a packet if larger than frag_size (add a header). Otherwise just pass down. Only add a * header if fragmentation is needed ! */ public Object down(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); long size = msg.getLength(); num_sent_msgs.incrementAndGet(); if (size > frag_size) { if (log.isTraceEnabled()) { log.trace( new StringBuilder("message's buffer size is ") .append(size) .append(", will fragment ") .append("(frag_size=") .append(frag_size) .append(')')); } fragment(msg); // Fragment and pass down return null; } break; case Event.VIEW_CHANGE: handleViewChange((View) evt.getArg()); break; case Event.CONFIG: Object ret = down_prot.down(evt); if (log.isDebugEnabled()) log.debug("received CONFIG event: " + evt.getArg()); handleConfigEvent((Map<String, Object>) evt.getArg()); return ret; } return down_prot.down(evt); // Pass on to the layer below us }
public Object down(Event evt) { if (drop_next && evt.getType() == Event.MSG) { drop_next = false; return null; } return super.down(evt); }
public Object down(Event evt) { if (evt.getType() == Event.MSG) { Message msg = (Message) evt.getArg(); if (msg.getLength() > 0) { try { Long payload = msg.getObject(); if (payload != null) { if (payload == seqno) { synchronized (this) { if (num_discards < 3) { num_discards++; return null; } } } if (payload == duplicate) { // inject a duplicate message super.down( evt); // pass it down, will passed down a second time by the default // down_prot.down(evt) } } } catch (Throwable t) {; } } } return down_prot.down(evt); }
/** * <b>Callback</b>. Called by superclass when event may be handled. * * <p><b>Do not use <code>PassDown</code> in this method as the event is passed down by default by * the superclass after this method returns !</b> * * @return boolean Defaults to true. If false, event will not be passed down the stack. */ public boolean handleDownEvent(Event evt) { switch (evt.getType()) { case Event.CONNECT: passDown(evt); try { group_addr = (String) evt.getArg(); } catch (ClassCastException cce) { Trace.error( "GMS.handleDownEvent(CONNECT)", "group address must " + "be a string (group name) to make sense"); } impl.join(local_addr); passUp(new Event(Event.CONNECT_OK)); startEventHandlerThread(); return false; // don't pass down: was already passed down case Event.DISCONNECT: impl.leave((Address) evt.getArg()); passUp(new Event(Event.DISCONNECT_OK)); stopEventHandlerThread(); initState(); return true; // pass down } return impl.handleDownEvent(evt); }
// Priority handling, otherwise GMS.down(DISCONNECT) would block ! // Similar to FLUSH protocol public void receiveDownEvent(Event evt) { if (evt.getType() == Event.BLOCK_OK) { passDown(evt); return; } super.receiveDownEvent(evt); }
public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); ForkHeader hdr = (ForkHeader) msg.getHeader(id); if (hdr == null) break; if (hdr.fork_stack_id == null) throw new IllegalArgumentException("header has a null fork_stack_id"); Protocol bottom_prot = get(hdr.fork_stack_id); return bottom_prot != null ? bottom_prot.up(evt) : this.unknownForkHandler.handleUnknownForkStack(msg, hdr.fork_stack_id); case Event.VIEW_CHANGE: for (Protocol bottom : fork_stacks.values()) bottom.up(evt); break; case Event.STATE_TRANSFER_OUTPUTSTREAM: if (!process_state_events) break; getStateFromMainAndForkChannels(evt); return null; case Event.STATE_TRANSFER_INPUTSTREAM: if (!process_state_events) break; setStateInMainAndForkChannels((InputStream) evt.getArg()); return null; } return up_prot.up(evt); }
/** * If event is a message, if it is fragmented, re-assemble fragments into big message and pass up * the stack. */ public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); FragHeader hdr = (FragHeader) msg.getHeader(this.id); if (hdr != null) { // needs to be defragmented unfragment(msg, hdr); // Unfragment and possibly pass up return null; } else { num_received_msgs.incrementAndGet(); } break; case Event.VIEW_CHANGE: handleViewChange((View) evt.getArg()); break; case Event.CONFIG: Object ret = up_prot.up(evt); if (log.isDebugEnabled()) log.debug("received CONFIG event: " + evt.getArg()); handleConfigEvent((Map<String, Object>) evt.getArg()); return ret; } return up_prot.up(evt); // Pass up to the layer above us by default }
public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); LockingHeader hdr = (LockingHeader) msg.getHeader(id); if (hdr == null) break; Request req = (Request) msg.getObject(); if (log.isTraceEnabled()) log.trace("[" + local_addr + "] <-- [" + msg.getSrc() + "] " + req); switch (req.type) { case GRANT_LOCK: case RELEASE_LOCK: handleLockRequest(req); break; case LOCK_GRANTED: handleLockGrantedResponse(req.lock_name, req.owner, msg.getSrc()); break; case LOCK_DENIED: handleLockDeniedResponse(req.lock_name, req.owner); break; case CREATE_LOCK: handleCreateLockRequest(req.lock_name, req.owner); break; case DELETE_LOCK: handleDeleteLockRequest(req.lock_name); break; case COND_SIG: case COND_SIG_ALL: handleSignalRequest(req); break; case LOCK_AWAIT: handleAwaitRequest(req.lock_name, req.owner); handleLockRequest(req); break; case DELETE_LOCK_AWAIT: handleDeleteAwaitRequest(req.lock_name, req.owner); break; case SIG_RET: handleSignalResponse(req.lock_name, req.owner); break; case CREATE_AWAITER: handleCreateAwaitingRequest(req.lock_name, req.owner); break; case DELETE_AWAITER: handleDeleteAwaitingRequest(req.lock_name, req.owner); break; default: log.error("Request of type " + req.type + " not known"); break; } return null; case Event.VIEW_CHANGE: handleView((View) evt.getArg()); break; } return up_prot.up(evt); }
public Object down(Event evt) { if (channel != null) { if (evt.getType() == Event.MSG && !(channel.isConnected() || channel.isConnecting())) throw new IllegalStateException("channel is not connected"); return channel.down(evt); } return null; }
public Object up(Event evt) { switch (evt.getType()) { case Event.VIEW_CHANGE: handleView(evt.getArg()); break; } return up_prot.up(evt); }
public Object down(Event evt) { switch (evt.getType()) { case Event.SET_LOCAL_ADDRESS: local_addr = (Address) evt.getArg(); break; } return down_prot.down(evt); }
@SuppressWarnings("unchecked") public Object up(Event evt) { if (evt.getType() == Event.CONFIG) { if (bind_addr == null) { Map<String, Object> config = (Map<String, Object>) evt.getArg(); bind_addr = (InetAddress) config.get("bind_addr"); } return up_prot.up(evt); } return super.up(evt); }
public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); // Do something with the event, e.g. extract the message and remove a header. // Optionally pass up break; } return up_prot.up(evt); // Pass up to the layer above us }
public Object down(Event evt) { switch (evt.getType()) { case Event.TMP_VIEW: case Event.VIEW_CHANGE: handleViewChange((View) evt.getArg()); break; case Event.GET_STATE: Address target; StateTransferInfo info = (StateTransferInfo) evt.getArg(); if (info.target == null) { target = determineCoordinator(); } else { target = info.target; if (target.equals(local_addr)) { log.error("%s: cannot fetch state from myself", local_addr); target = null; } } if (target == null) { log.debug("%s: first member (no state)", local_addr); up_prot.up(new Event(Event.GET_STATE_OK, new StateTransferInfo())); } else { Message state_req = new Message(target) .putHeader(this.id, new StateHeader(StateHeader.STATE_REQ)) .setFlag(Message.Flag.DONT_BUNDLE, Message.Flag.OOB, Message.Flag.SKIP_BARRIER); log.debug("%s: asking %s for state", local_addr, target); // suspend sending and handling of message garbage collection gossip messages, // fixes bugs #943480 and #938584). Wake up when state has been received /*if(log.isDebugEnabled()) log.debug("passing down a SUSPEND_STABLE event"); down_prot.down(new Event(Event.SUSPEND_STABLE, new Long(info.timeout)));*/ waiting_for_state_response = true; start = System.currentTimeMillis(); down_prot.down(new Event(Event.MSG, state_req)); } return null; // don't pass down any further ! case Event.CONFIG: Map<String, Object> config = (Map<String, Object>) evt.getArg(); if (config != null && config.containsKey("flush_supported")) { flushProtocolInStack = true; } break; case Event.SET_LOCAL_ADDRESS: local_addr = (Address) evt.getArg(); break; } return down_prot.down(evt); // pass on to the layer below us }
/** * An event is to be sent down the stack. The layer may want to examine its type and perform some * action on it, depending on the event's type. If the event is a message MSG, then the layer may * need to add a header to it (or do nothing at all) before sending it down the stack using <code> * down_prot.down()</code>. In case of a GET_ADDRESS event (which tries to retrieve the stack's * address from one of the bottom layers), the layer may need to send a new response event back up * the stack using <code>up_prot.up()</code>. */ public Object down(Event evt) { GMS.GmsHeader hdr = getGMSHeader(evt); if (hdr != null && needsAuthentication(hdr)) { // we found a join request message - now add an AUTH Header Message msg = (Message) evt.getArg(); AuthHeader authHeader = new AuthHeader(this.auth_token); msg.putHeader(this.id, authHeader); } if (evt.getType() == Event.SET_LOCAL_ADDRESS) local_addr = (Address) evt.getArg(); return down_prot.down(evt); }
public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); NakAckHeader2 hdr = (NakAckHeader2) msg.getHeader(ID); if (hdr != null && hdr.getType() == NakAckHeader2.MSG) { long seqno = hdr.getSeqno(); msgs.add(seqno); System.out.println("-- received message #" + seqno + " from " + msg.getSrc()); } break; } return null; }
/** * handle the UP event. * * @param evt - the event being send from the stack */ public void up(Event evt) { passUp(evt); switch (evt.getType()) { case Event.CONFIG: passUp(evt); if (Trace.trace) { Trace.info("UDP.up()", "received CONFIG event: " + evt.getArg()); } handleConfigEvent((HashMap) evt.getArg()); return; } passUp(evt); }
public Object down(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); NakAckHeader2 hdr = (NakAckHeader2) msg.getHeader(ID); if (hdr == null) break; if (hdr.getType() == NakAckHeader2.XMIT_REQ) { SeqnoList seqnos = (SeqnoList) msg.getObject(); System.out.println("-- XMIT-REQ: request retransmission for " + seqnos); for (Long seqno : seqnos) xmit_requests.add(seqno); } break; } return null; }
public Object down(Event evt) { Object retval = super.down(evt); switch (evt.getType()) { case Event.VIEW_CHANGE: for (Address logical_addr : members) { PhysicalAddress physical_addr = (PhysicalAddress) down_prot.down(new Event(Event.GET_PHYSICAL_ADDRESS, logical_addr)); if (physical_addr != null && !initial_hosts.contains(physical_addr)) { dynamic_hosts.addIfAbsent(physical_addr); } } break; } return retval; }
/** * <b>Callback</b>. Called by superclass when event may be handled. * * <p><b>Do not use <code>PassUp</code> in this method as the event is passed up by default by the * superclass after this method returns !</b> * * @return boolean Defaults to true. If false, event will not be passed up the stack. */ public boolean handleUpEvent(Event evt) { switch (evt.getType()) { case Event.CONNECT_OK: // sent by someone else, but WE are responsible for sending this ! case Event.DISCONNECT_OK: // dito (e.g. sent by UDP layer) return false; case Event.SET_LOCAL_ADDRESS: local_addr = (Address) evt.getArg(); if (print_local_addr) { System.out.println( "\n-------------------------------------------------------\n" + "2.1GMS: address is " + local_addr + "\n-------------------------------------------------------"); } return true; // pass up case Event.SUSPECT: try { event_queue.add(evt); } catch (Exception e) { } return true; // pass up case Event.MERGE: try { event_queue.add(evt); } catch (Exception e) { } return false; // don't pass up case Event.FLUSH_OK: synchronized (flush_mutex) { flush_rsp = (FlushRsp) evt.getArg(); flush_mutex.notify(); } return false; // don't pass up case Event.REBROADCAST_MSGS_OK: synchronized (rebroadcast_mutex) { rebroadcast_mutex.notify(); } return false; // don't pass up } return impl.handleUpEvent(evt); }
public Object down(final Event evt) { switch (evt.getType()) { case Event.MSG: final Message msg = (Message) evt.getArg(); if (msg.getDest() != null) break; // only process multicast messages if (next == null) // view hasn't been received yet, use the normal transport break; // we need to copy the message, as we cannot do a msg.setSrc(next): the next retransmission // would use 'next' as destination ! Message copy = msg.copy(true); short hdr_ttl = (short) (loopback ? view_size - 1 : view_size); DaisyHeader hdr = new DaisyHeader(hdr_ttl); copy.setDest(next); copy.putHeader(getId(), hdr); msgs_sent++; if (loopback) { if (log.isTraceEnabled()) log.trace(new StringBuilder("looping back message ").append(msg)); if (msg.getSrc() == null) msg.setSrc(local_addr); Executor pool = msg.isFlagSet(Message.Flag.OOB) ? oob_pool : default_pool; pool.execute(() -> up_prot.up(evt)); } return down_prot.down(new Event(Event.MSG, copy)); case Event.VIEW_CHANGE: handleView((View) evt.getArg()); break; case Event.TMP_VIEW: view_size = ((View) evt.getArg()).size(); break; case Event.SET_LOCAL_ADDRESS: local_addr = (Address) evt.getArg(); break; } return down_prot.down(evt); }
public Object down(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); if (msg.getLength() == 0 && !encrypt_entire_message) break; try { if (queue_down) { log.trace("queueing down message as no session key established: %s", msg); downMessageQueue.put(msg); // queue messages if we are waiting for a new key } else { // make sure the down queue is drained first to keep ordering if (!suppliedKey) drainDownQueue(); encryptAndSend(msg); } } catch (Exception e) { log.warn("unable to send message down", e); } return null; case Event.VIEW_CHANGE: View view = (View) evt.getArg(); log.debug("new view: " + view); if (!suppliedKey) handleViewChange(view, false); break; case Event.SET_LOCAL_ADDRESS: local_addr = (Address) evt.getArg(); log.debug("set local address to %s", local_addr); break; case Event.TMP_VIEW: view = (View) evt.getArg(); if (!suppliedKey) { // if a tmp_view then we are trying to become coordinator so // make us keyserver handleViewChange(view, true); } break; } return down_prot.down(evt); }
/** * 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> * down_prot.down()</code> or c) the event (or another event) is sent up the stack using <code> * up_prot.up()</code>. */ public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); // If we have a join or merge request --> authenticate, else pass up GMS.GmsHeader gms_hdr = getGMSHeader(evt); if (gms_hdr != null && needsAuthentication(gms_hdr)) { AuthHeader auth_hdr = (AuthHeader) msg.getHeader(id); if (auth_hdr == null) throw new IllegalStateException("found GMS join or merge request but no AUTH header"); if (!handleAuthHeader(gms_hdr, auth_hdr, msg)) // authentication failed return null; // don't pass up } break; } if (!callUpHandlers(evt)) return null; return up_prot.up(evt); }
public Object up(Event evt) { Message msg; Address dst, src; Unicast2Header hdr; switch (evt.getType()) { case Event.MSG: msg = (Message) evt.getArg(); dst = msg.getDest(); if (dst == null || msg.isFlagSet(Message.NO_RELIABILITY)) // only handle unicast messages break; // pass up // changed from removeHeader(): we cannot remove the header because if we do loopback=true // at the // transport level, we will not have the header on retransmit ! (bela Aug 22 2006) hdr = (Unicast2Header) msg.getHeader(this.id); if (hdr == null) break; src = msg.getSrc(); switch (hdr.type) { case Unicast2Header.DATA: // received regular message handleDataReceived(src, hdr.seqno, hdr.conn_id, hdr.first, msg, evt); return null; // we pass the deliverable message up in handleDataReceived() case Unicast2Header.XMIT_REQ: // received ACK for previously sent message handleXmitRequest(src, hdr.seqno, hdr.high_seqno); break; case Unicast2Header.SEND_FIRST_SEQNO: handleResendingOfFirstMessage(src, hdr.seqno); break; case Unicast2Header.STABLE: stable(msg.getSrc(), hdr.conn_id, hdr.seqno, hdr.high_seqno); break; default: log.error("UnicastHeader type " + hdr.type + " not known !"); break; } return null; } return up_prot.up(evt); // Pass up to the layer above us }
public Object down(Event evt) { switch (evt.getType()) { case Event.TMP_VIEW: case Event.VIEW_CHANGE: List<Address> new_members = ((View) evt.getArg()).getMembers(); synchronized (members) { members.clear(); if (new_members != null && !new_members.isEmpty()) members.addAll(new_members); } return down_prot.down(evt); case Event.MSG: Message msg = (Message) evt.getArg(); // Do something with the event, e.g. add a header to the message // Optionally pass down break; } return down_prot.down(evt); // Pass on to the layer below us }
/** * If event is a message, if it is fragmented, re-assemble fragments into big message and pass up * the stack. */ public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); FragHeader hdr = (FragHeader) msg.getHeader(this.id); if (hdr != null) { // needs to be defragmented Message assembled_msg = unfragment(msg, hdr); if (assembled_msg != null) up_prot.up(new Event(Event.MSG, assembled_msg)); return null; } else { num_received_msgs++; } break; case Event.VIEW_CHANGE: handleViewChange((View) evt.getArg()); break; } return up_prot.up(evt); // Pass up to the layer above us by default }