|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface ILnkPeerEndpoint
The Link Peer Endpoint interface.
A peer endpoint represents an endpoint in a peer-peer communication link. It specifies the API and semantics using which two peer entities can perform the bidirectional exchange of packets. In addition, peer endpoint serve as routing nodes in link trees. Link trees are formed when peer endpoints utilize other peer endpoint implementations in performing their function. Since multiple layered endpoints can use the same underlying endpoint, this can result in complex link trees. Peer endpoints serve as routing nodes' in such link trees to enable to correct movement of packets and events through the trees to reach their intended recipients,
Users Of an Endpoint
There are two types of users of a peer endpoint. The first, an end user of
the endpoint, interacts with the endpoint to exchange of packets with its
peer at the other end of the link. The other is a layered endpoint upstream
from an underlying endpoint in its link tree that treats the underlying
endpoint as a routing node that routes packets and events appropriately
through the link tree so that the layered link can perform its function
correctly.
Endpoint Name
A running instance of a peer endpoint is associated with a name that uniquely
identifies the endpoint in the link registry (see LnkRegistry
) and,
therefore, in a Neeve application instance. This name is either specified by
the user or, if not, typically, identifies the address of the link's other
peer endpoint. Layered endpoints' creation machinery uses this name (among
other things) to identify whether to attach to an existing endpoint in a
link tree or create a new one. The getName()
method returns an
endpoint's name.
Endpoint Creation
There is no single specified mechanism to create a peer endpoint. It is
the implementation that determines how the peer endpoint object comes into
existence and how it implements the exchange of packets with the peer.
However, the most common creation mechanism employed is the client-server
model of creation. In this model, server entities listen for link connection
establishment requests using the ILnkServerEndpoint
. On the other
end of the link, the user uses the ILnkClientEndpoint
to establish
the link connection to the listening server endpoint. Upon successful
establishment, both the client and the server endpoints create a peer
endpoint each and hand it to the user. These peer endpoints are then used
for the bidirectional exchange of packets through the connected link.
A created peer endpoint is part of a link tree. Link implementations that do not utilize other link implementations to perform their function are called root links and peer endpoints of such link types form the root of link trees. Composite links are formed by attaching additional link segments to existing links. Each node (endpoint) in a link tree is associated with a number called the Link Tree Port (LTP) that uniquely identifies and, thus, addresses the node relative to it's link tree.
Joining & Leaving an Endpoint
In order to send packets through and receive packets and other events from
a peer endpoint, a user must first join(short, com.neeve.link.ILnkEventHandler)
the endpoint. The event
handler through which packet and other events are dispatched to the user is
specified during the join. When done using the endpoint, the user should
leave(short, int)
the endpoint. Methods used to send packets through an endpoint
will throw an exception in case the user has not successfully joined the
endpoint prior to invoking those methods.
Packet IO
The packet receipt model prescribed by the peer endpoint is asynchronous in
nature. Basically, the model prescribes the following abstract steps for a
user to receive packets through the endpoint:
Step 1
The user associates the underlying implementation specific packet receipt
machinery with one or more dispatcher objects i.e. the machinery is setup
so that the driving of the associated dispatchers will cause packets sent
by the remote endpoint to arrive at the local endpoint.
Step 2
The user registers an event handler with the local endpoint through which
arriving packets are dispatched to the user.
Step 3
The user drives the packet receipt machinery by driving the dispatchers used
in step 1.
The packet receipt model does not prescribe how step 1 or step 3 works.
These steps are the collaborative responsibility of the root endpoint of a
link tree and the link container to which the tree belongs. Root endpoints
expose their participation in this process via a derivative of the ILnkRootEndpoint
interface. In most cases, the containers concern themselves
with assigning dispatchers to the read machinery of the link trees
that they contain and of driving those dispatchers. The root endpoints
concern themselves with associating the assigned dispatcher with their
read machinery, This interface only concerns itself with prescribing that
packet receipt is asynchronous in nature, is driven by a set of dispatchers,
is controlled collaboratively by the link tree's root endpoint and container
and received packets are dispatched through installed event handlers (see
join(short, com.neeve.link.ILnkEventHandler)
). Additional interfaces and implementations embodying specific
threading models and implementation policies are more prescriptive.
The packet sending model, on the other hand, is simpler (being top-down in
nature as opposed to the bottom-up asynchronous nature of the packet
receipt) and more prescriptive. The sending of packets through a peer
endpoint is accomplished in two steps. In the first step, the user enqueues
a packet to be sent at the local endpoint using enque(short, com.neeve.pkt.PktPacket, com.neeve.link.ILnkPeerEndpoint.FlushContext, int)
. The second
step involves transmitting the entire locally enqueued batch of packets to
the remote endpoint using the flush(short, com.neeve.link.ILnkPeerEndpoint.FlushContext)
method. The threading model
is free threaded i.e. the endpoint implementation must support the sending
of packets through the link using multiple concurrently executing threads.
The flushing of the a peer endpoint supports multiple flush IO semantics -
synchronous blocking, synchronous non-blocking and asynchronous. When a user
flushes an endpoint using the synchronous blocking flush mode, the flush
method does not return until all packets enqueued in the endpoint are
transmitted out to the remote endpoint (note that transmitted does not
imply delivered). When flushed using the synchronous non-blocking flush mode,
the endpoint attempts to flush all enqueued packets before returning. However,
in case the link is congested and the calling thread would have to block
and wait for congestion to abate before all enqueued packets could be
flushed, the thread does not block. It returns immediately with information
indicating that the flush did not complete and the user should retry the
flush later. Lastly, the asynchronous flush mode is similar to the
synchronous non-blocking flush mode in that the calling thread does not
wait for the congestion to abate before returning. The difference is that
before returning, the endpoint schedules the flush for background completion
using a dispatcher provided by the caller. Upon return from the call, the
user is responsible for driving the dispatcher to complete the flush. No
packets can be enqueued or the endpoint flushed while an async flush in
in progress. Once the flush completes, the endpoint dispatches a flush
completion signalling the user that packet enqueuing and endpoint flushing
can commence once again. For more information see ILnkPeerEndpoint.FlushContext
,
ILnkPeerEndpoint.SynchronousBlockingFlushContext
, ILnkPeerEndpoint.SynchronousNonBlockingFlushContext
and ILnkPeerEndpoint.AsynchronousFlushContext
.
An endpoint implementation is required to provide some mechanism that does not force the user to always have to keep track as to when to flush the endpoint. In the event that the user enques packets into the endpoint and and does not subsequently flush the endpoint, the endpoint implementation should implement a mechanism that the enqueued packets are ultimately flushed. The mechanism implemented would obviously be suited and determined by the functionality served by the endpoint. It may not be the most optimal mechanism from a throughput and latency standpoint but the important point is that enqueued packets do not remain in the endpoint indefinitely. A common mechanism is to provide an adaptive flush mechanism alongwith an auto flush size. When a user enqueues packets into the endpoint and the auto flush size is exceeded, the endpoint can automatically flush the endpoint. In case the auto flush size is not reached and the user stops enqueuing packets and does not flush the endpoint, a timer mechanism could kick in to flush the endpoint. Even more sophisticated would be a mechanism by which the timer interval could be dynamically adjusted based on the users enque and flush pattern.
With regard to link trees, packets sent by the user (via enque() and flush()) flow 'down' the tree towards the root link while received packets and other events flow 'up' the tree towards the leaf nodes. It is permissible for packets to be sent from and packets and other events to be generated from any node in the tree including intermediate nodes. Thus, peer endpoints play the dual role of communication endpoints of a link as well as routing nodes in a link tree.
The sending of packets 'down' a link tree is fairly straightfoward. A sent packet is forwarded through links that form a path from the packet source endpoint to the root of the tree. It is the propagation of received packets and 'up' the tree that gets tricky since a received packet is destined for one and only one endpoint (node) in the tree. Each packet travelling up a link tree contains the LTP of the endpoint that it is destined for. Event handlers serve as 'routing tables' for such packets. Each event handler registered with an endpoint is associated with an LTP. A packet received by the endpoint is dispatched through event handler matching the LTP contained in the received packet. A handler registered using the LTP of the endpoint with which it being registered receives packets that are destined for the endpoint i.e. for an end user of an endpoint. Other handlers are intended for the forwarding of packets up the link tree towards their target endpoint.
Endpoint Threading Model
As mentioned above, the threading model for sending packets is simple i.e.
it is free threaded and an endpoint implementation is required to support
concurrent sends using multiple threads. With regard to the receipt of
packets, the endpoint permits single or multiple threads (dispatchers) to
drive the receipt of packets through an endpoint. Therefore, an endpoint
implementation needs to support the following read-write threading models:
Single-Threaded ReadWrite
In this model, the endpoint is operated
entirely using a single thread.
Single-Threaded Read, Single-Threaded Write
In this model, a
single thread drives the read machinery and a single thread writes through
the endpoint with these threads potentially being different.
Single-Threaded Read, Multi-Threaded Write
In this model, a single
thread drives the endpoint read machinery while the endpoint supports write
using concurrently executing threads.
Multi-Threaded Read, Single-Threaded Write
In this model, multiple
threads drives the endpoint read machinery while the endpoint only supports
a single thread writing through the endpoint at any point in time.
Multi-Threaded Read, Multi-Threaded Write
This is the most flexible
model in which multiple threads drive the endpoint's read machinery and
multiple threads can write concurrently through the endpoint.
The root endpoint of a link tree instance determines the threading model
that applies to all endpoints in the tree. Generally, the threading model
to use is fixed at creation time and remains invariant through the life
of the root endpoint (i.e. the life of the link tree). The user can get
a link tree's threading model via ILnkRootEndpoint.getThreadingModel()
.
Endpoint States
ILnkPeerEndpoint.State
enumerates the various states of a peer endpoint. A freshly
created peer endpoint starts in the ILnkPeerEndpoint.State.CONNECTED
state. The
following depicts the various possible state transitions of an endpoint
(states in [] are optional states in a transition):
ILnkPeerEndpoint.State.CONNECTED
--close()-->[ILnkPeerEndpoint.State.CLOSING
]-->ILnkPeerEndpoint.State.CLOSED
ILnkPeerEndpoint.State.CONNECTED
--failure-->ILnkPeerEndpoint.State.FAILED
--close()-->[ILnkPeerEndpoint.State.CLOSING
]-->ILnkPeerEndpoint.State.CLOSED
The getState()
method returns the state of an endpoint.
Link Containers and Registry
The Link Registry LnkRegistry
is comprised of a set of link
containers (LnkContainer
) each uniquely identified by name.
Peer endpoints register themselves with a container in the registry
when created and remove themselves from their container when closed.
The setContainer(com.neeve.link.LnkContainer)
method allows a user to migrate a link from
one container to another (migration is only permitted if the link's read
machinery is off at the time of the migration).
As mentioned above, link containers are responsible for managing the read machinery for all the link trees that they contain. A user does not create links via the link containers. It does so using the link factory. Once a link is established, it adds itself to the appropriate container. The container validates that the threading model that the link was configured to run with agrees with the threading model that it is configured to work with. If not, the link is rejected and the link creation failed.
Artificial Failure Inducement
A peer endpoint is responsible for keeping track of the reachability to
the remote endpoint. The link is said to have failed when the local
endpoint determines that the remote endpoint is no longer reachable either
due to the failure of the remote endpoint or due to some communication
failure between the endpoints. Upon failure, the local endpoint dispatches
an event to notify the user of the failure and transitions to the
ILnkPeerEndpoint.State.FAILED
state (The user needs to register a handler for this
event in order to get notified).
The fail(java.lang.Exception)
method allows for a user to force fail a link. The
successful invocation of the fail method causes the endpoint to terminate
the underlying connection and notify the user in a manner indistiguishable
from a genuine failure of the link. This method is present to enable
the user to force fail the connection at strategic points in its execution
to test fault handling and recovery scenarios.
Closing
A peer endpoint kicks off the endpoint closure machinery when the last user
has left the endpoint. The endpoint transitions to ILnkPeerEndpoint.State.CLOSING
when the closure is kicked off and to ILnkPeerEndpoint.State.CLOSED
upon completion
of the close. An endpoint can also be closed by invoking close(short)
.
This method is equivalent to leave(short, int)
except that the closure is
kicked off even if the caller has not previously joined the endpoint.
Nested Class Summary | |
---|---|
static class |
ILnkPeerEndpoint.AsynchronousFlushContext
Context for asynchronous flushing through a peer endpoint.. |
static interface |
ILnkPeerEndpoint.EventHandlerChain
Interface to manage a link's peer endpoint event handler chain. |
static class |
ILnkPeerEndpoint.FlushContext
Base class for all flushing contexts. |
static class |
ILnkPeerEndpoint.State
Specifies the peer endpoint states. |
static class |
ILnkPeerEndpoint.SynchronousBlockingFlushContext
Context for synchronous blocking flushing through a peer endpoint.. |
static class |
ILnkPeerEndpoint.SynchronousNonBlockingFlushContext
Context for synchronous non-blocking flushing through a peer endpoint.. |
Field Summary |
---|
Fields inherited from interface com.neeve.link.ILnkEndpoint |
---|
IOFLAG_FLUSH_FORCE, IOFLAG_FLUSH_SUPPRESS, IOFLAG_IMMEDIATE_DISPATCH, IOFLAG_NO_ASYNC, LVFLAG_ALLOW_FLUSH_PENDING, LVFLAG_SUPPRESS_IMPLICT_CLOSE |
Method Summary | |
---|---|
void |
close(short ltp)
Close the endpoint. |
boolean |
enque(short ltp,
PktPacket packet,
ILnkPeerEndpoint.FlushContext flushContext,
int flags)
Enque a packet for flush. |
void |
fail(Exception e)
Force fail the endpoint. |
void |
flush(short ltp,
ILnkPeerEndpoint.FlushContext flushContext)
Flush enqueued packets to the remote endpoint. |
Object |
getAttachment()
Get the endpoint attachment. |
LnkContainer |
getContainer()
Get the endpoint's link container. |
int |
getEnqueuedSize()
Return the serialized length of the enqueued packets. |
ILnkPeerEndpoint.EventHandlerChain |
getHandlerChain()
Get the endpoint's end user event handler chain. |
short |
getLtp()
Get the endpoint LTP. |
String |
getName()
Get the endpoint name. |
String |
getNameInternal()
Get the endpoint's internal name. |
long |
getNextSequenceNum()
Get the next sequence number from the endpoints sequence number space. |
ILnkRootEndpoint |
getRootEndpoint()
Get the root endpoint of the endpoint's link tree. |
ILnkPeerEndpoint.State |
getState()
Get the current state of the endpoint. |
String |
getType()
Get the endpoint link type. |
Date |
getWhenCreated()
Get when the endpoint was created. |
boolean |
isGroupEndpoint()
Get whether this endpoint can participate in group communication. |
boolean |
isJoined(short ltp)
Get whether a user has joined the endpoint. |
boolean |
isReadOperational()
Indicates whether the endpoint's link tree's read machinery is operational. |
boolean |
isRootEndpoint()
Get whether this endpoint is the root endpoint of the link tree. |
void |
join(short ltp,
ILnkEventHandler handler)
Join an endpoint |
void |
leave(short ltp,
int flags)
Leave an endpoint |
void |
setAttachment(Object object)
Attach an opaque object to the endpoint. |
void |
setContainer(LnkContainer container)
Migrate the endpoint to another link container. |
Method Detail |
---|
void setAttachment(Object object)
This method attaches an opaque object to this endpoint.
Object getAttachment()
String getName()
String getNameInternal()
Each endpoint generates a unique name to identify itself. The internally
generated name is used as the name of the endpoint (returned by the
getName()
method) in case the user does not override it (e.g. by
using the 'name' property in the link descriptor). This method returns
the internal name generated by the endpoint for itself. The name returned
by this method will be the same as the name returned by getName()
in case the user has not overriden the endpoints internally generated
name.
String getType()
This method returns the type of the link for this endpoint. This is only used for tracing and debugging purposes.
short getLtp()
Date getWhenCreated()
ILnkPeerEndpoint.State getState()
long getNextSequenceNum()
The peer endpoint is responsible for managing the sequence number space for packets transmitted by the endpoint's end user. The sequence number space is a monotonically increasing space. This method returns the next value from that space.
ILnkPeerEndpoint.EventHandlerChain getHandlerChain()
An event handler chain is used to direct events dispatched to the endpoint's end user through a series of linked handlers for the purpose of intercepting and filtering the events. This method returns the event handler chain for the peer endpoint.
boolean isGroupEndpoint()
Some link implementations connect to entities that manage communication groups. With such links, the user can join one or more communication groups and communicate with other members of the group. Groups are addressed using topics that are wildcard enabled hierarchical strings. The group communication semantics e.g. delivery reliability and ordering, membership management etc is defined by the link implementation.
boolean isRootEndpoint()
ILnkRootEndpoint getRootEndpoint()
boolean isReadOperational()
LnkContainer getContainer()
void setContainer(LnkContainer container) throws ELnkInvalidStateException, ELnkPrivateException, ELnkReadOperationalException, ELnkNotCompatibleException
container
- The container to which this endpoint is to be moved.
The method will do nothing in case this specifies the container in
which the endpoint is currently in.
ELnkInvalidStateException
- Thrown in case the user is attempting
to migrate a failed, closing or closed endpoint.
ELnkPrivateException
- Thrown in case the user is attempting to
migrate a private endpoint.
ELnkReadOperationalException
- Thrown in case the user is attempting
to migrate a link whose read is operational.
ELnkNotCompatibleException
- Thrown in case the endpoint is not
compatible with the new container.
This method migrates an endpoint to a new container. The endpoint can only be migrated in case the endpoint is in a connected state, is not a private endpoint, the read not operational on the endpoint's link tree and the threading model of the endpoint's link tree is compatible with the new container.
int getEnqueuedSize() throws ELnkInvalidStateException
ELnkInvalidStateException
- Thrown in case the user is attempting
to get the enqueued packet size in a failed or closed endpoint.boolean isJoined(short ltp)
ltp
- Specifies the LTP of the user for which to perform the check.
An caller should specify -1 or the LTP returned by the getLtp()
method to indicate an end user.
IllegalArgumentException
- Thrown in case the specified ltp is
invalid i.e. not between -1 and 255 both inclusive.join(short, com.neeve.link.ILnkEventHandler)
,
leave(short, int)
void join(short ltp, ILnkEventHandler handler) throws ELnkInvalidStateException, ELnkAlreadyJoinedException, ELnkMaxUsersReachedException
ltp
- Specifies the LTP of the user that is joining the endpoint.
An end user should specify either -1 or the LTP returned by the
getLtp()
method in this parameter.handler
- The event handler to be associated with the joining
user. Each event that is dispatched by an endpoint is targeted towards
one or more endpoint nodes in the link tree to which the source endpoint
belongs. The handler through which an event is to be dispatched is
determined by the LTP of the endpoint node to which the event is
targeted. The mechanism by which events are mapped to their recipients
is event type specific. For example, packet event recipients are
determined via the LTP present in a packet while flush completion
events are dispatched to endpoints that have issued enque or flush
requests that resulted in incomplete flushes with the flush scheduled
for asynchronous completion. Refer to event type documentation for
how the receipients for events of a particular type is determined.
IllegalArgumentException
- Thrown in case the specified ltp is
invalid i.e. not between -1 and 255 both inclusive.
ELnkInvalidStateException
- Thrown in case the user is attempting
to join a failed, closing or closed endpoint.
ELnkAlreadyJoinedException
- Thrown in case a user with the
specified LTP has already joined the endpoint.
ELnkMaxUsersReachedException
- Thrown in case the maximum number
of configured users for the link has already been reached. Default is
LnkLTPAuthority.MAX_LTP
+ 1.
This method is used by a user of a peer endpoint to register itself with
the endpoint. Once the user is registered, it can send packets through
the endpoint via the enque(short, com.neeve.pkt.PktPacket, com.neeve.link.ILnkPeerEndpoint.FlushContext, int)
and flush(short, com.neeve.link.ILnkPeerEndpoint.FlushContext)
methods and to
receive packets and other events from the endpoint through the handler
specified in handler parameter. When an event is dispatched by
the endpoint (including packet events), the endpoint determines the
event's recipient endpoint(s) using an event type specific mechanism.
The event is then dispatched through the registered event handlers
corresponding to the LTPs of the event receipient(s). In case no event
handler is found, the event is dropped.
An end user should specify an LTP of -1 (indicating 'this' endpoint) or
the value obtained from the getLtp()
method. A layered endpoint
user should specify its own LTP when invoking this method.
isJoined(short)
,
leave(short, int)
void leave(short ltp, int flags) throws ELnkInvalidStateException, ELnkNotJoinedException, ELnkFlushInProgressException, ELnkOpFailedException
ltp
- Specifies the LTP of the user that is leaving the endpoint.
An end user should specify either -1 or the LTP returned by the
getLtp()
method in this parameter.flags
- Flags used to qualify the leave operation. The following
flags are permissible for use here:ILnkEndpoint.LVFLAG_ALLOW_FLUSH_PENDING
ILnkEndpoint.LVFLAG_SUPPRESS_IMPLICT_CLOSE
IllegalArgumentException
- Thrown in case the specified ltp is
invalid i.e. not between -1 and 255 both inclusive.
ELnkInvalidStateException
- Thrown in case the user is attempting
to leave a closed endpoint.
ELnkNotJoinedException
- Thrown in case the user with the specified
LTP has not joined the endpoint.
ELnkFlushInProgressException
- Thrown in case there is a flush
currently in progress that is pending async completion. This exception
will not be thrown if ILnkEndpoint.LVFLAG_ALLOW_FLUSH_PENDING
is specified in the flags parameter.
ELnkOpFailedException
- Thrown in case the leave resulted in a
close being invoked and there was an exception encountered during the
close operation.
This method is used by a user of an endpoint to deregister itself from
the endpoint. If the leave results in all users having left the endpoint,
this method issues an implicit close on the endpoint unless instructed
not to do so via the flags. See close(short)
for details on
the close operation.
An end user should specify an LTP of -1 (indicating 'this' endpoint) or
the value obtained from the getLtp()
method. A layered endpoint
should specify its own LTP when invoking this method.
join(short, com.neeve.link.ILnkEventHandler)
,
close(short)
boolean enque(short ltp, PktPacket packet, ILnkPeerEndpoint.FlushContext flushContext, int flags) throws ELnkInvalidStateException, ELnkNotOwnerException, ELnkNotJoinedException, ELnkFlushInProgressException, ELnkOpFailedException
packet
- The packet to enqueltp
- Specifies the LTP of the user that is issuing the enque.
This parameter is only used in case (1) the provided flush context
specified in the flushContext parameter in as async flush context
(2) the enque operation results in an automatic flush (3) the flush
could not be completed synchronously and was scheduled for asynchronous
completion. In this case, this LTP is marked as a recipient of the
flush completion event. When the asynchronous flush completes, the flush
completion event is dispatched through the event handler associated with
this LTP. An end user should specify either -1 or the LTP obtained
from the getLtp()
method. This parameter is ignored in case the
user has provided a synchronous blocking or synchronous non-blocking
flush context.flushContext
- A context object indicating the IO semantics to
be used in case the link is automatically flushed from within this
method (due to some policy implemented by the endpoint such as auto
flush based on packet queue size) alongwith runtime context information
related to the flushflags
- Flags used to qualify the enque operation. The following
flags are permissible for use here:ILnkEndpoint.IOFLAG_FLUSH_SUPPRESS
ILnkEndpoint.IOFLAG_FLUSH_FORCE
This method serializes and enques a packet at the endpoint for flush at
a later point. Once serialized, the packet queue is conditionally flushed
depending on internal auto flush policies implemented by the endpoint.
See flush(short, com.neeve.link.ILnkPeerEndpoint.FlushContext)
for more information on how the flushContext
parameter is used and updated by the endpoint in case of an auto flush.
In the event that the enque causes the endpoint to e automatically
flushed and the flush is scheduled for asynchronous completion, the
LTP supplied in the ltp parameter is stored and the flush
completion event dispatched through the handler associated with the
LTP when the flush completes.
In case of an implicit flush, this method may choose to flush only a
part of the set of enqueued packets. The caller should either specify
the use ILnkEndpoint.IOFLAG_FLUSH_FORCE
flags or explicitly
invoke flush(short, com.neeve.link.ILnkPeerEndpoint.FlushContext)
to ensure that all enqueued packets are flushed.
The sender should assume that the act of enqueuing a packet in an
endpoint transfers ownership of the packet to the endpoint i.e. the
endpoint may choose to hold onto the non-serialized packet
subsequent to return from the method. If the endpoint assumes packet
ownership, it does so by incrementing the packet's reference count.
Although the caller can conditionally decide what to do with the packet
by inspecting the packet's reference count (PktPacket.getOwnerCount()
,
the simplest, consistent and optimal operation to perform post enque
is to PktPacket.dispose()
the packet. If the endpoint did not
assume ownership of the packet, then the packet will be recycled
through its pool (if configured for its type) for the next send by
the caller. If it did assume ownership, then the packet will be
recycled through the pool when the endpoint is done with the packet.
The endpoint never assumes ownership of a packet if this method throws
an exception (checked or unchecked).
IllegalArgumentException
- Thrown in case the specified ltp is
invalid i.e. not between -1 and 255 both inclusive.
ELnkInvalidStateException
- Thrown in case the user is attempting
to enque a packet on a failed or closed endpoint
ELnkNotOwnerException
- Thrown in case this method is invoked
with an async flush context and by a thread that is not the owner of
the dispatcher specified in the context.
ELnkNotJoinedException
- Thrown in case the user with the specified
LTP has not joined the endpoint.
ELnkFlushInProgressException
- Thrown in case a previous implicit
flush during enque or explicit flush could not complete synchronously,
the user elected asynchronous completion of the flush and the flush has
not yet completed. It is illegal to enque a packet into an endpoint
that is attempting to complete a flush asynchronously.
ELnkOpFailedException
- Thrown in case an error was encountered
during the enqueing or, more likely, the automatic flushing of the
endpoint.void flush(short ltp, ILnkPeerEndpoint.FlushContext flushContext) throws ELnkInvalidStateException, ELnkNotOwnerException, ELnkNotJoinedException, ELnkFlushInProgressException, ELnkOpFailedException
ltp
- Specifies the LTP of the user that is issuing this flush.
This parameter is only used in case (1) the provided flush context
specified in the flushContext parameter in as async flush context
(2) the flush could not be completed synchronously and is scheduled for
asynchronous completion. In this case, this LTP is marked as a recipient
of the flush completion event. When the asynchronous flush completes,
the flush completion event is dispatched through the event handler
associated with this LTP. An end user should either specify -1 or the
LTP obtained from the getLtp()
method. This parameter is ignored
in case the user has provided a synchronous blocking or synchronous
non-blocking flush context.flushContext
- A context object indicating the IO semantics to
be used in case the link is automatically flushed from within this
method (due to some policy implemented by the endpoint such as auto
flush based on packet queue size) alongwith runtime context information
related to the flush
IllegalArgumentException
- Thrown in case the specified ltp is
invalid i.e. not between -1 and 255 both inclusive.
ELnkInvalidStateException
- Thrown in case the user is attempting
to flush a failed or closed endpoint.
ELnkNotOwnerException
- Thrown in case this method is invoked
with an async flush context and by a thread that is not the owner of
the dispatcher specified in the context.
ELnkNotJoinedException
- Thrown in case the user with the specified
LTP has not joined the endpoint.
ELnkFlushInProgressException
- Thrown in case a previous implicit
flush during enque or explicit flush could not complete synchronously,
the user elected asynchronous completion of the flush and the flush has
not yet completed. It is illegal to flush an endpoint that is attempting
to complete a flush asynchronously.
ELnkOpFailedException
- Thrown in case an error was encountered
during the flushing of the endpoint.
This method flushes enqueued packets to the remote endpoint. The flush
context determines the IO semantics used for the flush operation i.e.
sync blocking, sync non-blocking or async. In case the user has requested
for async flush, the user should check the contents of the flush context
upon return from this method. In case the flush did not complete
synchronously, the user needs to drive the specified dispatcher. That
will asynchronously drive the flush operation. Upon completion of the
flush, the flush context will be updated to indicate that the flush has
completed and an LnkEvents.EVENT_FLUSH_COMPLETE
event will be
dispatched to the user through its registered event handler. It is
illegal to enque packets into or flush the endpoint while an asynchronous
flush is in progress.
For a flush completing asynchronously, in the event that the endpoint fails and the user is dispatched a failure event before the flush completion event is dispatched, the user will never receive a flush completion event.
For a flush completing asynchronously, it is possible for the flush completion event to be dispatched to the user by a thread different from the owner thread of the dispatcher provided in the asynchronous flush context. The user should check for an appropriately process such a case.
void fail(Exception e) throws ELnkInvalidStateException, ELnkOpFailedException
e
- The exception that describes the failure. The force failing
of the endpoint will ultimately result in the dispatch of an
LnkEvents.EVENT_FAILURE
event to the user. This exception
object will be attached to that event to describe the failure.
ELnkInvalidStateException
- Thrown in case the user is attempting
to fail a failed or closed endpoint or an endpoint whose read machinery
is not operational.
ELnkOpFailedException
- Thrown in case an error was encountered
during the failing of the endpoint.
This method force fails the endpoint. The successful invocation of this
method causes the endpoint to terminate the underlying connection and
dispatch an LnkEvents.EVENT_FAILURE
event through all
registered event handlers. The event is always dispatched after the
method returns and the state of the endpoint at the time the failure
event is dispatched is identical to its state when a genuine failure
occurs. This method is present to enable the user to force fail a link
connection at strategic points in its execution to test fault handling
and recovery scenrios. It is guaranteed that, after this method returns,
the user will not receive any received packets and all enque and flush
attempts will fail.
A user can only force fail an endpoint that has its read machinery operational. This method will return with an exception indicating an invalid state in case the endpoint is force failed without the read machinery operating.
void close(short ltp) throws ELnkOpFailedException
ltp
- Specifies the LTP of the user that is issuing the close.
An end user should specify either -1 or the LTP obtained from the
getLtp()
method.
IllegalArgumentException
- Thrown in case the specified ltp is
invalid i.e. not between -1 and 255 both inclusive.
ELnkOpFailedException
- Thrown in case an error was encountered
during the closing of the endpoint.
This method first invokes leave(short, int)
using the specified ltp with
implicit flush suppressed. Then, in case all users have left the
endpoint, this method transitions the endpoint to ILnkPeerEndpoint.State.CLOSING
and kicks off the close machinery. The closure process may need to
be scheduled for asynchronous completion in case it needs to wait for
some async operation to complete or to be cancelled. Once the close
is complete, the endpoint is transitioned to ILnkPeerEndpoint.State.CLOSED
.
The transition from closing to closed state needs to be driven by the
following dispatchers/threads:
- Dispatchers associated with read machinery of the link tree to which
the closing endpoint belongs.
- Dispatchers associated with any flush operation pending asynhronous
completion in the closing endpoint.
- Dispatchers managed and driven internal to the closing endpoint
The user needs to continue to drive any of the above dispatchers that
are under its control.
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |