Kea 2.7.4
|
Abstract interface for receiving NameChangeRequests. More...
#include <ncr_io.h>
Classes | |
class | RequestReceiveHandler |
Abstract class for defining application layer receive callbacks. More... | |
Public Types | |
typedef boost::shared_ptr< RequestReceiveHandler > | RequestReceiveHandlerPtr |
Defines a smart pointer to an instance of a request receive handler. | |
enum | Result { SUCCESS , TIME_OUT , STOPPED , ERROR } |
Defines the outcome of an asynchronous NCR receive. More... | |
Public Member Functions | |
NameChangeListener (RequestReceiveHandlerPtr recv_handler) | |
Constructor. | |
virtual | ~NameChangeListener () |
Destructor. | |
bool | amListening () const |
Returns true if the listener is listening, false otherwise. | |
bool | isIoPending () const |
Returns true if the listener has an IO call in progress. | |
void | startListening (const isc::asiolink::IOServicePtr &io_service) |
Prepares the IO for reception and initiates the first receive. | |
void | stopListening () |
Closes the IO source and stops listen logic. | |
Protected Member Functions | |
virtual void | close ()=0 |
Abstract method which closes the IO source. | |
virtual void | doReceive ()=0 |
Initiates an IO layer asynchronous read. | |
void | invokeRecvHandler (const Result result, NameChangeRequestPtr &ncr) |
Calls the NCR receive handler registered with the listener. | |
virtual void | open (const isc::asiolink::IOServicePtr &io_service)=0 |
Abstract method which opens the IO source for reception. | |
void | receiveNext () |
Initiates an asynchronous receive. | |
Abstract interface for receiving NameChangeRequests.
NameChangeListener provides the means to:
It implements the high level logic flow to listen until a request arrives, invoke the implementation's handler and return to listening for the next request.
It provides virtual methods that allow derivations supply implementations to open the appropriate IO source, perform a listen, and close the IO source.
The overall design is based on a callback chain. The listener's caller (the application) supplies an "application" layer callback through which it will receive inbound NameChangeRequests. The listener derivation will supply its own callback to the IO layer to process receive events from its IO source. This is referred to as the NameChangeRequest completion handler. It is through this handler that the NameChangeRequest layer gains access to the low level IO read service results. It is expected to assemble NameChangeRequests from the inbound data and forward them to the application layer by invoking the application layer callback registered with the listener.
The application layer callback is structured around a nested class, RequestReceiveHandler. It consists of single, abstract operator() which accepts a result code and a pointer to a NameChangeRequest as parameters. In order to receive inbound NCRs, a caller implements a derivation of the RequestReceiveHandler and supplies an instance of this derivation to the NameChangeListener constructor. This "registers" the handler with the listener.
To begin listening, the caller invokes the listener's startListener() method, passing in an IOService instance. This in turn will pass the IOService into the virtual method, open(). The open method is where the listener derivation performs the steps necessary to prepare its IO source for reception (e.g. opening a socket, connecting to a database).
Assuming the open is successful, startListener will call receiveNext, to initiate an asynchronous receive. This method calls the virtual method, doReceive(). The listener derivation uses doReceive to instigate an IO layer asynchronous receive passing in its IO layer callback to handle receive events from the IO source.
As stated earlier, the derivation's NameChangeRequest completion handler MUST invoke the application layer handler registered with the listener. This is done by passing in either a success status and a populated NameChangeRequest or an error status and an empty request into the listener's invokeRecvHandler method. This is the mechanism by which the listener's caller is handed inbound NCRs.
typedef boost::shared_ptr<RequestReceiveHandler> isc::dhcp_ddns::NameChangeListener::RequestReceiveHandlerPtr |
isc::dhcp_ddns::NameChangeListener::NameChangeListener | ( | RequestReceiveHandlerPtr | recv_handler | ) |
|
inlinevirtual |
|
inline |
Returns true if the listener is listening, false otherwise.
A true value indicates that the IO source has been opened successfully, and that receive loop logic is active. This implies that closing the IO source will interrupt that operation, resulting in a callback invocation.
Definition at line 316 of file ncr_io.h.
Referenced by invokeRecvHandler(), and startListening().
|
protectedpure virtual |
Abstract method which closes the IO source.
The derivation uses this method to perform the steps needed to "close" the IO source.
If | the implementation encounters an error it MUST throw it as an isc::Exception or derivative. |
Implemented in isc::dhcp_ddns::NameChangeUDPListener.
Referenced by stopListening().
|
protectedpure virtual |
Initiates an IO layer asynchronous read.
The derivation uses this method to perform the steps needed to initiate an asynchronous read of the IO source with the derivation's IO layer handler as the IO completion callback.
If | the implementation encounters an error it MUST throw it as an isc::Exception or derivative. |
Implemented in isc::dhcp_ddns::NameChangeUDPListener.
Referenced by receiveNext().
|
protected |
Calls the NCR receive handler registered with the listener.
This is the hook by which the listener's caller's NCR receive handler is called. This method MUST be invoked by the derivation's implementation of doReceive.
NOTE: The handler invoked by this method MUST NOT THROW. The handler is at application level and should trap and handle any errors at that level, rather than throw exceptions. If an error has occurred prior to invoking the handler, it will be expressed in terms a failed result being passed to the handler, not a throw. Therefore any exceptions at the handler level are application issues and should be dealt with at that level.
This method does wrap the handler invocation within a try-catch block as a fail-safe. The exception will be logged but the receive logic will continue. What this implies is that continued operation may or may not succeed as the application has violated the interface contract.
result | contains that receive outcome status. |
ncr | is a pointer to the newly received NameChangeRequest if result is NameChangeListener::SUCCESS. It is indeterminate other wise. |
Definition at line 108 of file ncr_io.cc.
References amListening(), isc::dhcp_ddns::dhcp_ddns_logger, isc::dhcp_ddns::DHCP_DDNS_NCR_RECV_NEXT_ERROR, isc::dhcp_ddns::DHCP_DDNS_UNCAUGHT_NCR_RECV_HANDLER_ERROR, ERROR, LOG_ERROR, and receiveNext().
Referenced by isc::dhcp_ddns::NameChangeUDPListener::receiveCompletionHandler().
|
inline |
Returns true if the listener has an IO call in progress.
A true value indicates that the listener has an asynchronous IO in progress which will complete at some point in the future. Completion of the call will invoke the registered callback. It is important to understand that the listener and its related objects should not be deleted while there is an IO call pending. This can result in the IO service attempting to invoke methods on objects that are no longer valid.
|
protectedpure virtual |
Abstract method which opens the IO source for reception.
The derivation uses this method to perform the steps needed to prepare the IO source to receive requests.
io_service | is the IOService that process IO events. |
If | the implementation encounters an error it MUST throw it as an isc::Exception or derivative. |
Implemented in isc::dhcp_ddns::NameChangeUDPListener.
Referenced by startListening().
|
protected |
Initiates an asynchronous receive.
Sets context information to indicate that IO is in progress and invokes the derivation's asynchronous receive method, doReceive. Note doReceive should not be called outside this method to ensure context information integrity.
Derivation's | doReceive method may throw isc::Exception upon error. |
Definition at line 85 of file ncr_io.cc.
References doReceive().
Referenced by invokeRecvHandler(), isc::dhcp_ddns::NameChangeUDPListener::receiveCompletionHandler(), and startListening().
void isc::dhcp_ddns::NameChangeListener::startListening | ( | const isc::asiolink::IOServicePtr & | io_service | ) |
Prepares the IO for reception and initiates the first receive.
Calls the derivation's open implementation to initialize the IO layer source for receiving inbound requests. If successful, it starts the first asynchronous read by receiveNext.
io_service | is the IOService that will handle IO event processing. |
NcrListenError | if the listener is already "listening" or in the event the open or doReceive methods fail. |
Definition at line 58 of file ncr_io.cc.
References amListening(), isc_throw, open(), receiveNext(), stopListening(), and isc::Exception::what().
void isc::dhcp_ddns::NameChangeListener::stopListening | ( | ) |
Closes the IO source and stops listen logic.
Calls the derivation's implementation of close and marks the state as not listening.
Definition at line 91 of file ncr_io.cc.
References close(), isc::dhcp_ddns::dhcp_ddns_logger, isc::dhcp_ddns::DHCP_DDNS_NCR_LISTEN_CLOSE_ERROR, and LOG_ERROR.
Referenced by isc::dhcp_ddns::NameChangeUDPListener::~NameChangeUDPListener(), and startListening().