com.neeve.link
Interface ILnkPeerEndpoint

All Superinterfaces:
ILnkEndpoint
All Known Implementing Classes:
LnkPeerEndpoint

public interface ILnkPeerEndpoint
extends ILnkEndpoint

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.

Threading:
See the Threading Model section above for a description of a peer endpoints threading model.

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

setAttachment

void setAttachment(Object object)
Attach an opaque object to the endpoint.

This method attaches an opaque object to this endpoint.

Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getAttachment

Object getAttachment()
Get the endpoint attachment.

Returns:
Returns the current attachment.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getName

String getName()
Get the endpoint name.

Returns:
Returns the name that uniquely identifies the endpoint in the link registry.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getNameInternal

String getNameInternal()
Get the endpoint's internal name.

Returns:
Returns the name that is generated by the link to identify itself.

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.

Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getType

String getType()
Get the endpoint link type.

Returns:
Returns a string describing the link type for this endpoint.

This method returns the type of the link for this endpoint. This is only used for tracing and debugging purposes.

Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getLtp

short getLtp()
Get the endpoint LTP.

Returns:
Returns the identifier of this link endpoint as a node in a link tree. This identifier is used to route events up the link tree to the endpoint. Each link peer endpoint has a unique LTP within the link tree to which it belongs.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getWhenCreated

Date getWhenCreated()
Get when the endpoint was created.

Returns:
Returns a date object indicating when this endpoint was created. The date object stores the creation time measured to the nearest millsecond.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getState

ILnkPeerEndpoint.State getState()
Get the current state of the endpoint.

Returns:
Returns the endpoints state.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getNextSequenceNum

long getNextSequenceNum()
Get the next sequence number from the endpoints sequence number space.

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.

Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getHandlerChain

ILnkPeerEndpoint.EventHandlerChain getHandlerChain()
Get the endpoint's end user event handler chain.

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.

Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

isGroupEndpoint

boolean isGroupEndpoint()
Get whether this endpoint can participate in group communication.

Returns:
Returns true if this endpoint connects to an entity that manages communication groups.

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.

Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

isRootEndpoint

boolean isRootEndpoint()
Get whether this endpoint is the root endpoint of the link tree.

Returns:
Returns true if this is the root endpoint of the link tree to which this endpoint belongs.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getRootEndpoint

ILnkRootEndpoint getRootEndpoint()
Get the root endpoint of the endpoint's link tree.

Returns:
Returns the root endpoint in the endpoint's link tree.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

isReadOperational

boolean isReadOperational()
Indicates whether the endpoint's link tree's read machinery is operational.

Returns:
Returns true if the read machinery is operational and false otherwise.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getContainer

LnkContainer getContainer()
Get the endpoint's link container.

Returns:
Returns the endpoint's link container. A null return value indicates that the endpoint is designated as private and is not in any link container.
Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

setContainer

void setContainer(LnkContainer container)
                  throws ELnkInvalidStateException,
                         ELnkPrivateException,
                         ELnkReadOperationalException,
                         ELnkNotCompatibleException
Migrate the endpoint to another link container.

Parameters:
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.
Throws:
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.

Threading:
This method is safe for concurrent access by multiple threads independent of the threading model of the endpoint's link tree.

getEnqueuedSize

int getEnqueuedSize()
                    throws ELnkInvalidStateException
Return the serialized length of the enqueued packets.

Returns:
Returns the serialized length of the enqueued packets.
Throws:
ELnkInvalidStateException - Thrown in case the user is attempting to get the enqueued packet size in a failed or closed endpoint.
Threading:
This method is safe for concurrent access by multiple threads in case the endpoint's link tree is configured for multi-threaded write.

isJoined

boolean isJoined(short ltp)
Get whether a user has joined the endpoint.

Parameters:
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.
Throws:
IllegalArgumentException - Thrown in case the specified ltp is invalid i.e. not between -1 and 255 both inclusive.
See Also:
join(short, com.neeve.link.ILnkEventHandler), leave(short, int)
Threading:
This method is safe for concurrent access by multiple threads in case the endpoint's link tree is configured for multi-threaded read or write. The endpoint implementation is expected to synchronize the installation of event handlers with the act of looking up and dispatching triggered events. This allows for te join status of users to be interrogated at any point during the lifetime of the endpoint.

join

void join(short ltp,
          ILnkEventHandler handler)
          throws ELnkInvalidStateException,
                 ELnkAlreadyJoinedException,
                 ELnkMaxUsersReachedException
Join an endpoint

Parameters:
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.
Throws:
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.

See Also:
isJoined(short), leave(short, int)
Threading:
This method is safe for concurrent access by multiple threads in case the endpoint's link tree is configured for multi-threaded read or write. The endpoint implementation is expected to synchronize the installation of event handlers with the act of looking up and dispatching triggered events. This allows for event handlers to be installed at any point during the lifetime of the endpoint (before the endpoint fails or is closed)

leave

void leave(short ltp,
           int flags)
           throws ELnkInvalidStateException,
                  ELnkNotJoinedException,
                  ELnkFlushInProgressException,
                  ELnkOpFailedException
Leave an endpoint

Parameters:
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
Throws:
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.

See Also:
join(short, com.neeve.link.ILnkEventHandler), close(short)
Threading:
This method is safe for concurrent access by multiple threads in case the endpoint's link tree is configured for multi-threaded read or write. The endpoint implementation is expected to synchronize the removal of event handlers with the act of looking up and dispatching triggered events. This allows for event handlers to be removed at any point during the lifetime of the endpoint (before the endpoint fails or is closed)

enque

boolean enque(short ltp,
              PktPacket packet,
              ILnkPeerEndpoint.FlushContext flushContext,
              int flags)
              throws ELnkInvalidStateException,
                     ELnkNotOwnerException,
                     ELnkNotJoinedException,
                     ELnkFlushInProgressException,
                     ELnkOpFailedException
Enque a packet for flush.

Parameters:
packet - The packet to enque
ltp - 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 flush
flags - Flags used to qualify the enque operation. The following flags are permissible for use here:
- ILnkEndpoint.IOFLAG_FLUSH_SUPPRESS
- ILnkEndpoint.IOFLAG_FLUSH_FORCE
Returns:
Returns true in case the method did attempt to automatically flush the packet queue. Returns false in case the packet was only enqueued and no flush was attempted.

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).

Throws:
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.
Threading:
This method is safe for concurrent access by multiple threads in case the endpoint's link tree is configured for multi-threaded write. Furthermore, in case an asynchronous flush context is specified, the calling thread must be the owner thread of the dispatcher associated with the asynchronous flush context.

flush

void flush(short ltp,
           ILnkPeerEndpoint.FlushContext flushContext)
           throws ELnkInvalidStateException,
                  ELnkNotOwnerException,
                  ELnkNotJoinedException,
                  ELnkFlushInProgressException,
                  ELnkOpFailedException
Flush enqueued packets to the remote endpoint.

Parameters:
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
Throws:
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.

Threading:
This method is safe for concurrent access by multiple threads in case the endpoint's link tree is configured for multi-threaded write. Furthermore, in case an asynchronous flush context is specified, the calling thread must be the owner thread of the dispatcher associated with the asynchronous flush context.

fail

void fail(Exception e)
          throws ELnkInvalidStateException,
                 ELnkOpFailedException
Force fail the endpoint.

Parameters:
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.
Throws:
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.

Threading:
This method is safe for concurrent access by multiple threads in case the endpoint's link tree is configured for multi-threaded read or write.

close

void close(short ltp)
           throws ELnkOpFailedException
Close the endpoint.

Parameters:
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.
Throws:
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.

Threading:
This method is safe for concurrent access by multiple threads in case the endpoint's link tree is configured for multi-threaded read or write.


Copyright © 2015 Neeve Research, LLC. All Rights Reserved.