All Packages Class Hierarchy This Package Previous Next Index
Class iBus.layers.NAK
java.lang.Object
|
+----iBus.ProtocolObject
|
+----iBus.layers.NAK
- public class NAK
- extends ProtocolObject
- implements Runnable
NAK: Fully reliable, negative acknowledgements (NAK) multicast layer.
NAK uses immediate, receiver-initiated, NAK-based, unicast loss
notification combined with originator based unicast and multicast
retransmission (selectable). The NAK protocol is similar to RAMP (RFC 1485).
NAK does not implement fifo ordering nor the filtering of
duplicated messages. This is accomplished by a FIFO layer atop of NAK.
NAK only makes sure that each message is received at least once,
without caring about duplicates and messages that are out of order.
NAK also does not implement failure detection as this is
handled by a membership layer beneath NAK (REACH, for example).
NAK is designed for intranets. It assumes low bit-error rates
and that packet loss is mostly a result of receiver buffer overflow.
(For multicasting over the MBONE a nak layer similar to RTP (RFC 1889)
is more appropriate. RTP employs delayed, receiver-initiated,
multicast error notification. NAK can be extended in this respect, though).
NAK is fully reliable, i.e., it is both sender and receiver
reliable.
For that it takes advantage of the membership information which is delivered
to it by a membership layer beneath, in the
form of iBus.View events. When a membership
layer is present, NAK synchronizes with the receivers before it
flushes its internal retransmission cache. This increases the reliability
of the protocol considerably.
NAK relies only on negative
acknowledgements while transmitting an epoch of messages.
An epoch has a fixed size of typically 100 to 1000 messages.
At the end of an epoch, NAK waits until it has received a positive
acknowledgement from each surviving receiver. After this it flushes
its message retransmission cache and proceeds with sending the next epoch.
In the ideal case there is only one round of positive acknowledgements
for every epoch-size of messages.
NAK can be used without a membership layer beneath.
However, in such situation the protocol is only semi-reliable
(``best-effort'') since NAK has no way of synchronizing with its receivers
before flushing an internal message retransmission cache.
PARAMETERS:
-
epochsz: the size of an epoch. Number of messages (int). Default: 200
-
hbinterval: heartbeat interval in msec (int). Default: 5000
-
idleinterval: idle interval after which the sender starts transmitting
idle heartbeats, in msec (int). Default: 3000
-
senddelay: delay (msec) imposed inbetween the sending of subsequent
messages (int). Default: 0
-
retrinterval: minimum time interval inbetween subsequent retransmission
requests, in msec (int). Default: 10000.
-
flowcontrol: int: 0|1. Whether to perform flow control.
Default: 1 (flow control performed).
POSITION IN STACK:
-
Below FRAG, below FIFO, above any membership layer.
-
Example: "FRAG:FIFO:NAK:REACH"
LIMITS:
-
Tests so far have shown that NAK is very reliable even in situations
of high message traffic. If you nevertheless suffer message loss,
try increasing the
timeout parameter of the underlying membership protocol object,
REACH for example.
-
When REACH is used, then the following problem occurs: when an
application comes up, pushes a posting and then terminates, the posting
will most probably not be delivered to the receivers. The reason is
that a receiver's NAK layer first expects a view change from the talker.
However, view changes happen asynchronously which means that the
receiver's NAK will most probably discard the message since it hasn't
received the view change yet. There are workarounds
to fix the problem by somewhat decreasing the reliability of NAK.
None of those have been implemented yet:
the clean solution consists of using a real view change protocol object
such as PMBRSHIP beneath NAK. REACH is just a ``reachability'' layer.
DESIGN:
-
The NAK layer consists of the following main classes: NAK, ChannelInfo,
ReceiverInfo, IncomingChecker, and SenderInfo. See
class diagram.
-
NAK maintains one
ChannelInfo per channel it transmits to, in the channelInfos_ Hashtable.
A ChannelInfo object maintains one ReceiverInfo object per receiver
it knows about, in the receivers_ Hashtable. ChannelInfo finds out
about joining and leaving receivers by the membership layer beneath.
-
NAK maintains one IncomingChecker object per channel it is subscribed
to, in the incomingCheckers_ Hashtable. An IncomingChecker maintains
one SenderInfo per sender it knows about. A SenderInfo maintains a list
of the messages that are missing from the sender.
EVENTS PRODUCED:
-
Event.evProblemEvent on communication problems
-
Event.evLostMessage on lost message
-
Event.evRetransmitReq on detection of a missing message (NAK)
-
Event.evAck to acknowledge the receipt of a complete epoch
EVENTS HANDLED:
-
Event.evMessage: requests any missing messages
-
Event.evHeartbeat: got an idle heartbeat
-
Event.evRetransmitReq: got a message retransmission request
-
Event.evLostMessage: sender informs me that it cannot honor my
message retransmission request
-
Event.evView: got a membership change notification: a receiver
has joined, left, or crashed
-
Event.evAck: a receiver acknowledges that it has received a complete epoch
of messages
EVENTS CONSUMED:
-
Event.evRetransmitReq
-
Event.evAck
THREADS:
-
NAK.heartbeat: to send idle heartbeats
-
SenderInfo.sendRetransmitRequests: to send retransmit requests
-
NAK()
- Create a NAK object by initializing the ProtocolObject base class
-
dnInit()
- Initialize the protocol object after the protocol stack has been
created.
-
dnPush(iBusURL, MessageEvent)
- Called by the object above to send a message to a channel by
multicast or unicast communication, depending on the channel URL:
-
dnRegisterTalker(iBusURL)
- Called by the object above or by an iBus application to register
as a talker with a channel.
-
dnSubscribe(iBusURL)
- Subscribe to a channel.
-
dnTerminate()
- Terminate any threads in the protocol object.
-
dnUnregisterTalker(iBusURL)
- Called by the object above or by an iBus application to unregister
as a talker of a certain channel.
-
dnUnsubscribe(iBusURL)
-
Unsubscribe from a channel.
-
expectedInitialMsgs()
- Returns the number of initial messages that a new listener
may re-request.
-
getChannelInfos()
- Get the channelInfos_ table.
-
getEpochSize()
- Get the epoch size property.
-
getHBIntarval()
- Get the hb interval property.
-
getIdleIntarval()
- Get the idle interval property.
-
getRetrInterval()
- Get the retry interval property.
-
getRetrInterval(int)
- Set the retry interval property.
-
getSendDelay()
- Get the send delay property.
-
hbThread()
- Heartbeat thread.
-
isExpectInitialMessages()
- Check the ExpectInitialMessages property.
-
isFlowControl()
- Check whether we have to perform flow control.
-
isStatistics()
- Check the value of the statistics property.
-
run()
- NAK thread.
-
setExpectInitialMessages(boolean)
- Set the send delay property.
-
setHBInterval(int)
- Set the epoch size property.
-
setIdleInterval(int)
- Set the idle interval property.
-
setSendDelay(int)
- Set the send delay property.
-
setStatistics(boolean)
- Set the statistics property.
-
upHandleEvent(Event)
- Called by the protocol object beneath to pass an event up to me.
NAK
public NAK()
- Create a NAK object by initializing the ProtocolObject base class
dnInit
public synchronized void dnInit()
- Initialize the protocol object after the protocol stack has been
created. Also checks that the right parameters were given to the
protocol object.
- Overrides:
- dnInit in class ProtocolObject
dnTerminate
public void dnTerminate()
- Terminate any threads in the protocol object. The object is
unusable afterwards.
- Overrides:
- dnTerminate in class ProtocolObject
dnSubscribe
public synchronized void dnSubscribe(iBusURL channel) throws AlreadySubscribed, CommException
- Subscribe to a channel. This creates an IncomingChecker object and puts
it into incomingCheckers_.
- Parameters:
- channel - the iBus channel to subscribe to
- Throws: AlreadySubscribed
- if this stack has already
subscribed to the channel
- Throws: CommException
- in case of a communication
failure
- Overrides:
- dnSubscribe in class ProtocolObject
dnUnsubscribe
public synchronized void dnUnsubscribe(iBusURL channel) throws NotSubscribed, CommException
- Unsubscribe from a channel. Destroys the IncomingChecker for that
channel.
- Parameters:
- channel - the iBus channel to unsubscribe from
- Throws: NotSubscribed
- if this stack is
not subscribed to the channel
- Throws: CommException
- in case of a communication
failure
- Overrides:
- dnUnsubscribe in class ProtocolObject
dnRegisterTalker
public synchronized void dnRegisterTalker(iBusURL channel) throws AlreadyRegistered, CommException
- Called by the object above or by an iBus application to register
as a talker with a channel. dnRegisterTalker checks whether a matching
ChannelInfo exists in channelInfos_. If yes, clear its obsolete flag.
If not, create and add a new ChannelInfo object.
- Parameters:
- channel - the channel to register with
- Throws: AlreadyRegistered
- if this stack is already
registered with the channel
- Throws: CommException
- in case of a communication
error
- Overrides:
- dnRegisterTalker in class ProtocolObject
dnUnregisterTalker
public void dnUnregisterTalker(iBusURL channel) throws NotRegistered, CommException
- Called by the object above or by an iBus application to unregister
as a talker of a certain channel. Gets the ChannelInfo object for the
channel. If there are no messages in ChannelInfo.outgoing_ then
we remove the ChannelInfo. Otherwise we tag it as obsolete
such that it will be removed as soon as its message cache is empty.
- Parameters:
- channel - the channel to unregister from
- Throws: NotRegistered
- if this stack is not
registered with the channel
- Throws: CommException
- in case of a communication
error
- Overrides:
- dnUnregisterTalker in class ProtocolObject
dnPush
public void dnPush(iBusURL channel,
MessageEvent msg) throws CommException, NotRegistered
- Called by the object above to send a message to a channel by
multicast or unicast communication, depending on the channel URL:
- Parameters:
- channel - the destination channel of the posting
- msg - the message to be sent
- Throws: CommException
- on communication failure
- Throws: NotRegistered
- in case registerTalker was not called for
the channel
- Overrides:
- dnPush in class ProtocolObject
run
public void run()
- NAK thread.
- See Also:
- langRunnable
hbThread
protected void hbThread()
- Heartbeat thread. Iterate over all ChannelInfo objects. Check time
last message was sent. Deliver idle heartbeat on timeout.
If dnUnregisterCalled was called then tag the heartbeat with an
epoch-end flag.
expectedInitialMsgs
protected int expectedInitialMsgs()
- Returns the number of initial messages that a new listener
may re-request.
- Returns:
- the number of initial messages that a new listener
may re-request
upHandleEvent
public void upHandleEvent(Event event)
- Called by the protocol object beneath to pass an event up to me.
An event can be the arrival of a posting, the detection of a failure,
an acknowledgement, etc.
- Parameters:
- event - the event object to process
- Overrides:
- upHandleEvent in class ProtocolObject
getEpochSize
public int getEpochSize()
- Get the epoch size property.
- Returns:
- the epoch size property
getHBIntarval
public int getHBIntarval()
- Get the hb interval property.
- Returns:
- the hb interval property
setHBInterval
public void setHBInterval(int hi)
- Set the epoch size property.
- Parameters:
- hi - the new value of the epoch size property
getIdleIntarval
public int getIdleIntarval()
- Get the idle interval property.
- Returns:
- the idle interval property
setIdleInterval
public void setIdleInterval(int ii)
- Set the idle interval property.
- Parameters:
- ii - the new value of the idle interval property
getSendDelay
public int getSendDelay()
- Get the send delay property.
- Returns:
- the send delay property
setSendDelay
public void setSendDelay(int sd)
- Set the send delay property.
- Parameters:
- sd - the new value of the send delay property
setStatistics
public void setStatistics(boolean on)
- Set the statistics property.
- Parameters:
- on - the new value of the statistics property
isStatistics
public boolean isStatistics()
- Check the value of the statistics property.
- Returns:
- the value of the statistics property
isExpectInitialMessages
public boolean isExpectInitialMessages()
- Check the ExpectInitialMessages property.
- Returns:
- the ExpectInitialMessages property.
setExpectInitialMessages
public void setExpectInitialMessages(boolean on)
- Set the send delay property.
- Parameters:
- on - the new value of the ExpectInitialMessages property.
If the property is
set, then the first maxExpectedInitialMsgs_ messages are
always retransmitted. This is useful for applications
thst start, push a posting and terminate immediately. If
ExpectInitialMessages is false then the posting would not be
retranmsitted if it gets lots on the network.
getRetrInterval
public int getRetrInterval()
- Get the retry interval property.
- Returns:
- the retry interval property
getRetrInterval
public void getRetrInterval(int ri)
- Set the retry interval property.
- Parameters:
- ri - the retry interval property
isFlowControl
public boolean isFlowControl()
- Check whether we have to perform flow control.
- Returns:
- whether we have to perform flow control
getChannelInfos
protected Hashtable getChannelInfos()
- Get the channelInfos_ table.
- Returns:
- the channelInfos_ table
All Packages Class Hierarchy This Package Previous Next Index