Commit 71d45704 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[5074] Split developer's documentation of CPL and D2.

parent 2a1d9f49
...@@ -71,8 +71,10 @@ ...@@ -71,8 +71,10 @@
* - @subpage dhcpv6SignalBasedReconfiguration * - @subpage dhcpv6SignalBasedReconfiguration
* - @subpage dhcpv6Other * - @subpage dhcpv6Other
* - @subpage dhcpv4o6Dhcp6 * - @subpage dhcpv4o6Dhcp6
* - @subpage libprocess
* - @subpage cpl
* - @subpage cplSignals
* - @subpage d2 * - @subpage d2
* - @subpage d2CPL
* - @subpage d2ProcessDerivation * - @subpage d2ProcessDerivation
* - @subpage d2ConfigMgt * - @subpage d2ConfigMgt
* - @subpage d2NCRReceipt * - @subpage d2NCRReceipt
......
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -29,165 +29,6 @@ already, its background color will be blue and/or its details may not be shown. ...@@ -29,165 +29,6 @@ already, its background color will be blue and/or its details may not be shown.
sometimes through a small chain of typedefs. These typedefs are shown for sometimes through a small chain of typedefs. These typedefs are shown for
accuracy but are unimportant to a general discussion. accuracy but are unimportant to a general discussion.
@section d2CPL Controllable Process Layer (CPL)
D2 is built upon an abstract set of classes referred to as the Controllable
Process Layer or CPL. This layer provides the essentials for a controllable,
configurable, asynchronous process. They are the result of an effort to
distill the common facets of process control currently duplicated in Kea's
DHCP servers into a reusable construct. The classes which form this abstract
base are shown in the following class diagram:
@image html abstract_app_classes.svg "Controllable Process Layer Classes"
- isc::process::DControllerBase - provides all of the services necessary to manage
an application process class derived from isc::d2::DProcess. These services include:
- Command line argument handling
- Process instantiation and initialization
- Support for stand-alone execution
- Process event loop invocation and shutdown
It creates and manages an instance of isc::process::DProcessBase. The CPL is
designed for asynchronous event processing applications. It is constructed
to use ASIO library for IO processing. @c DControllerBase owns an
isc::asiolink::IOService instance and it passes this into the @c
DProcessBase constructor. It is this @c IOService that is used to drive the
process's event loop. The controller is designed to provide any interfaces
between the process it controls and the outside world.
@c DControllerBase provides configuration for its process via a JSON file
specified as a mandatory command line argument. The file structure is
expected be as follows:
{ "<module-name>": {<module-config>} }
where:
- module-name : is a label which uniquely identifies the
configuration data for the (i.e. the controlled process.)
It is the value returned by @ref
isc::process::DControllerBase::getAppName()
- module-config: a set of zero or more JSON elements which comprise
application's configuration values. Element syntax is governed
by those elements supported in isc::cc.
The file may contain an arbitrary number of other modules.
@todo Eventually, some sort of secure socket interface which supports remote
control operations such as configuration changes or status reporting will
likely be implemented.
- isc::process::DProcessBase - defines an asynchronous-event processor (i.e.
application) which provides a uniform interface to:
- Instantiate and initialize a process instance
- "Run" the application by starting its event loop
- Inject events to control the process
It owns an instance of @c DCfgMgrBase.
- isc::process::DCfgMgrBase - provides the mechanisms for managing an application's
configuration. This includes services for parsing sets of configuration
values, storing the parsed information in its converted form, and retrieving
the information on demand. It owns an instance of @c DCfgContextBase, which
provides a "global" context for information that is accessible before, during,
and after parsing.
- isc::process::DCfgContextBase - implements a container for configuration
information or "context". It provides a single enclosure for the storage of
configuration parameters or any other information that needs to accessible
within a given context.
The following sequence diagram shows how a configuration from file moves
through the CPL layer:
@image html config_from_file_sequence.svg "CPL Configuration From File Sequence"
The CPL classes will likely move into a common library.
@subsection cplSignals CPL Signal Handling
CPL supports interaction with the outside world via OS signals. The default
implementation supports the following signal driven behavior:
- SIGHUP receipt of this signal will cause a reloading of the configuration
file.
- SIGINT/SIGTERM receipt of either of these signals will initiate an
orderly shutdown.
CPL applications wait for for process asynchronous IO events through
isc::asiolink::IOService::run() or its variants. These calls are not
interrupted upon signal receipt as is the select() function and while
boost::asio provides a signal mechanism it requires linking in additional
libraries. Therefore, CPL provides its own signal handling mechanism to
propagate an OS signal such as SIGHUP to an IOSerivce as a ready event with a
callback.
isc::process::DControllerBase uses two mechanisms to carry out signal handling. It
uses isc::util::SignalSet to catch OS signals, and isc::process::IOSignalQueue to
propagate them to its isc::asiolink::IOService as instances of
isc::process::IOSignal.
This CPL signaling class hierarchy is illustrated in the following diagram:
@image html cpl_signal_classes.svg "CPL Signal Classes"
The mechanics of isc::process::IOSignal are straight forward. Upon construction it
is given the target isc::asiolink::IOService, the value of the OS signal to
send (e.g. SIGINT, SIGHUP...), and an isc::process::IOSignalHandler. This handler
should contain the logic the caller would normally execute in its OS signal
handler. Each isc::process::IOSignal instance has a unique identifier called its
sequence_id.
Internally, IOSignal creates a 1 ms, one-shot timer, on the given
IOService. When the timer expires its event handler invokes the caller's
IOSignalHandler passing it the sequence_id of the IOSignal.
Sending IOSignals is done through an isc::process::IOSignalQueue. This class is
used to create the signals, house them until they are delivered, and dequeue
them so they can be been handled. To generate an IOSignal when an OS signal
arrives, the process's OS signal handler need only call
isc::process::IOSignalQueue::pushSignal() with the appropriate values.
To dequeue the IOSignal inside the caller's IOSignalHandler, one simply
invokes isc::process::IOSignalQueue::popSignal() passing it the sequence_id
parameter passed to the handler. This method returns a pointer to
instigating IOSignal from which the value of OS signal (i.e. SIGINT,
SIGUSR1...) can be obtained. Note that calling popSignal() removes the
IOSignalPtr from the queue, which should reduce its reference count to
zero upon exiting the handler (unless a deliberate copy of it is made).
A typical isc::process::IOSignalHandler might be structured as follows:
@code
void processSignal(IOSignalId sequence_id) {
// Pop the signal instance off the queue.
IOSignalPtr signal = io_signal_queue_->popSignal(sequence_id);
int os_signal_value = signal->getSignum();
:
// logic based on the signal value
:
}
@endcode
IOSignal's handler invocation code will catch, log ,and then swallow any
exceptions thrown by an IOSignalHandler. This is done to protect the integrity
IOService context.
CPL integrates the use of the two mechanisms by registering the method,
isc::process::DControllerBase::osSignalHandler(), as the
isc::util::SignalSet::onreceipt_handler_. This configures SignalSet's internal
handler to invoke the method each time a signal arrives. When invoked, this
method will call isc::process::IOSignalQueue::pushSignal() to create an
isc::process::IOSignal, passing in the OS signal received and
isc::process::DControllerBase::ioSignalHandler() to use as the IOSignal's
ready event handler
The following sequence diagram depicts the initialization of signal handling
during startup and the subsequent receipt of a SIGHUP:
@image html cpl_signal_sequence.svg "CPL Signal Handling Sequence"
@section d2ProcessDerivation D2's CPL Derivations @section d2ProcessDerivation D2's CPL Derivations
D2's core application classes are DDNS-specific derivations of the CPL as show D2's core application classes are DDNS-specific derivations of the CPL as show
......
...@@ -30,7 +30,7 @@ spec_config.h: spec_config.h.pre ...@@ -30,7 +30,7 @@ spec_config.h: spec_config.h.pre
BUILT_SOURCES = spec_config.h process_messages.h process_messages.cc BUILT_SOURCES = spec_config.h process_messages.h process_messages.cc
# Ensure that the message file is included in the distribution # Ensure that the message file is included in the distribution
EXTRA_DIST = process_messages.mes EXTRA_DIST = process_messages.mes libprocess.dox
# Get rid of generated message files on a clean # Get rid of generated message files on a clean
CLEANFILES = *.gcno *.gcda spec_config.h process_messages.h process_messages.cc s-messages CLEANFILES = *.gcno *.gcda spec_config.h process_messages.h process_messages.cc s-messages
......
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
/**
@page libprocess libkea-process - Controllable Process Layer (CPL)
The D2 module was built upon an abstract set of classes referred to as the
Controllable Process Layer or CPL. These classes were originally included
in the src/bin/d2 directory because D2 was the only module using
them. The classes were later moved to their own libkea-process library with
the intent to be used as a base for creating new Kea modules.
The origin of the libkea-process implementation, being a part of D2 module,
is a reason why its design documentation is combined with the design
documentation of D2:
<a href="http://kea.isc.org/wiki/DhcpDdnsDesign">D2 Design</a>.
The following sections describe the architecture of the CPL and how
it can be used to implement new daemons in Kea.
@section cpl Controllable Process Layer (CPL)
This CPL provides the essentials for a controllable, configurable,
asynchronous process. They are the result of an effort to distill the
common facets of process control currently duplicated in Kea's
DHCP servers into a reusable construct. The classes which form this abstract
base are shown in the following class diagram:
@image html abstract_app_classes.svg "Controllable Process Layer Classes"
- isc::process::DControllerBase - provides all of the services necessary to manage
an application process class derived from isc::d2::DProcess. These services include:
- Command line argument handling
- Process instantiation and initialization
- Support for stand-alone execution
- Process event loop invocation and shutdown
It creates and manages an instance of isc::process::DProcessBase. The CPL is
designed for asynchronous event processing applications. It is constructed
to use ASIO library for IO processing. @c DControllerBase owns an
isc::asiolink::IOService instance and it passes this into the @c
DProcessBase constructor. It is this @c IOService that is used to drive the
process's event loop. The controller is designed to provide any interfaces
between the process it controls and the outside world.
@c DControllerBase provides configuration for its process via a JSON file
specified as a mandatory command line argument. The file structure is
expected be as follows:
{ "<module-name>": {<module-config>} }
where:
- module-name : is a label which uniquely identifies the
configuration data for the (i.e. the controlled process.)
It is the value returned by @ref
isc::process::DControllerBase::getAppName()
- module-config: a set of zero or more JSON elements which comprise
application's configuration values. Element syntax is governed
by those elements supported in isc::cc.
The file may contain an arbitrary number of other modules.
@todo Eventually, some sort of secure socket interface which supports remote
control operations such as configuration changes or status reporting will
likely be implemented.
- isc::process::DProcessBase - defines an asynchronous-event processor (i.e.
application) which provides a uniform interface to:
- Instantiate and initialize a process instance
- "Run" the application by starting its event loop
- Inject events to control the process
It owns an instance of @c DCfgMgrBase.
- isc::process::DCfgMgrBase - provides the mechanisms for managing an application's
configuration. This includes services for parsing sets of configuration
values, storing the parsed information in its converted form, and retrieving
the information on demand. It owns an instance of @c DCfgContextBase, which
provides a "global" context for information that is accessible before, during,
and after parsing.
- isc::process::DCfgContextBase - implements a container for configuration
information or "context". It provides a single enclosure for the storage of
configuration parameters or any other information that needs to accessible
within a given context.
The following sequence diagram shows how a configuration from file moves
through the CPL layer:
@image html config_from_file_sequence.svg "CPL Configuration From File Sequence"
The CPL classes will likely move into a common library.
@section cplSignals CPL Signal Handling
CPL supports interaction with the outside world via OS signals. The default
implementation supports the following signal driven behavior:
- SIGHUP receipt of this signal will cause a reloading of the configuration
file.
- SIGINT/SIGTERM receipt of either of these signals will initiate an
orderly shutdown.
CPL applications wait for for process asynchronous IO events through
isc::asiolink::IOService::run() or its variants. These calls are not
interrupted upon signal receipt as is the select() function and while
boost::asio provides a signal mechanism it requires linking in additional
libraries. Therefore, CPL provides its own signal handling mechanism to
propagate an OS signal such as SIGHUP to an IOSerivce as a ready event with a
callback.
isc::process::DControllerBase uses two mechanisms to carry out signal handling. It
uses isc::util::SignalSet to catch OS signals, and isc::process::IOSignalQueue to
propagate them to its isc::asiolink::IOService as instances of
isc::process::IOSignal.
This CPL signaling class hierarchy is illustrated in the following diagram:
@image html cpl_signal_classes.svg "CPL Signal Classes"
The mechanics of isc::process::IOSignal are straight forward. Upon construction it
is given the target isc::asiolink::IOService, the value of the OS signal to
send (e.g. SIGINT, SIGHUP...), and an isc::process::IOSignalHandler. This handler
should contain the logic the caller would normally execute in its OS signal
handler. Each isc::process::IOSignal instance has a unique identifier called its
sequence_id.
Internally, IOSignal creates a 1 ms, one-shot timer, on the given
IOService. When the timer expires its event handler invokes the caller's
IOSignalHandler passing it the sequence_id of the IOSignal.
Sending IOSignals is done through an isc::process::IOSignalQueue. This class is
used to create the signals, house them until they are delivered, and dequeue
them so they can be been handled. To generate an IOSignal when an OS signal
arrives, the process's OS signal handler need only call
isc::process::IOSignalQueue::pushSignal() with the appropriate values.
To dequeue the IOSignal inside the caller's IOSignalHandler, one simply
invokes isc::process::IOSignalQueue::popSignal() passing it the sequence_id
parameter passed to the handler. This method returns a pointer to
instigating IOSignal from which the value of OS signal (i.e. SIGINT,
SIGUSR1...) can be obtained. Note that calling popSignal() removes the
IOSignalPtr from the queue, which should reduce its reference count to
zero upon exiting the handler (unless a deliberate copy of it is made).
A typical isc::process::IOSignalHandler might be structured as follows:
@code
void processSignal(IOSignalId sequence_id) {
// Pop the signal instance off the queue.
IOSignalPtr signal = io_signal_queue_->popSignal(sequence_id);
int os_signal_value = signal->getSignum();
:
// logic based on the signal value
:
}
@endcode
IOSignal's handler invocation code will catch, log ,and then swallow any
exceptions thrown by an IOSignalHandler. This is done to protect the integrity
IOService context.
CPL integrates the use of the two mechanisms by registering the method,
isc::process::DControllerBase::osSignalHandler(), as the
isc::util::SignalSet::onreceipt_handler_. This configures SignalSet's internal
handler to invoke the method each time a signal arrives. When invoked, this
method will call isc::process::IOSignalQueue::pushSignal() to create an
isc::process::IOSignal, passing in the OS signal received and
isc::process::DControllerBase::ioSignalHandler() to use as the IOSignal's
ready event handler
The following sequence diagram depicts the initialization of signal handling
during startup and the subsequent receipt of a SIGHUP:
@image html cpl_signal_sequence.svg "CPL Signal Handling Sequence"
*/
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment