/** * Prepare this layer to receive messages from above */ @Override // GemStoneAddition public void start() throws Exception { TimeScheduler timer; timer=stack != null ? stack.timer : null; if(timer == null) throw new Exception("TOTAL.start(): timer is null"); reqTbl=new TreeMap(); upTbl=new TreeMap(); retransmitter=new AckSenderWindow(new Command(), AVG_RETRANSMIT_INTERVAL); }
/** * Replace the original message with a broadcast request sent to the * sequencer. The original bcast message is stored locally until a reply * to bcast is received from the sequencer * * @param msg the message to broadcast * @param id the local sequence ID to use */ private void _sendBcastRequest(Message msg, long id) { // i. Store away the message while waiting for the sequencer's reply // ii. Send a bcast request immediatelly and also schedule a // retransmission synchronized(reqTbl) { reqTbl.put(Long.valueOf(id), msg); } _transmitBcastRequest(id); retransmitter.add(id, msg); }
UnicastHeader hdr=new UnicastHeader(UnicastHeader.DATA, seqno); if(entry.sent_msgs == null) { // first msg to peer 'dst' entry.sent_msgs=new AckSenderWindow(this, timeout, timer); // use the protocol stack's timer entry.sent_high_prio_msgs = new AckSenderWindow(this, timeout, timer); entry.sent_high_prio_msgs.add(seqno, tmp); entry.numSentHighPrioMsgs++; long hm = this.numSentHighPrioMsgs.incrementAndGet(); entry.sent_msgs.add(seqno, tmp); // add *including* UnicastHeader, adds to retransmitter entry.numSentMsgs++; entry.sentMsgsBytes += tmp.size();
/** The number of messages in all Entry.sent_msgs tables (haven't received an ACK yet) */ public int getNumberOfUnackedMessages() { int num=0; Entry entry; synchronized(connections) { for(Iterator it=connections.values().iterator(); it.hasNext();) { entry=(Entry)it.next(); if(entry.sent_msgs != null) num+=entry.sent_msgs.size(); num+=entry.sent_high_prio_msgs.size(); } } return num; }
/** * Send the bcast request with the given localSeqID * * @param seqID the local sequence id of the */ private void _transmitBcastRequest(long seqID) { Message reqMsg; // i. If NULL_STATE, then ignore, just transient state before // shutting down the retransmission thread // ii. If blocked, be patient - reschedule // iii. If the request is not pending any more, acknowledge it // iv. Create a broadcast request and send it to the sequencer if(state == NULL_STATE) { if(log.isInfoEnabled()) log.info(ExternalStrings.TOTAL_TRANSMIT_BCAST_REQ_0__IN_NULL_STATE, seqID); return; } if(state == BLOCK) return; synchronized(reqTbl) { if(!reqTbl.containsKey(Long.valueOf(seqID))) { retransmitter.ack(seqID); return; } } reqMsg=new Message(sequencerAddr, addr, new byte[0]); reqMsg.putHeader(getName(), new Header(Header.REQ, seqID, NULL_ID)); passDown(new Event(Event.MSG, reqMsg)); }
retransmitter.ack(header.localSequenceID); id=header.localSequenceID;
/** * Handle the stop() method travelling down the stack. * <p/> * The local addr is set to null, since after a Start->Stop->Start * sequence this member's addr is not guaranteed to be the same */ @Override // GemStoneAddition public void stop() { try { stateLock.writeLock().acquire(); try { state=NULL_STATE; retransmitter.reset(); reqTbl.clear(); upTbl.clear(); addr=null; } finally { stateLock.writeLock().release(); } } catch(InterruptedException e) { Thread.currentThread().interrupt(); // GemStoneAddition log.error(e.getMessage()); } }