diff options
author | Marcin Siodelski <marcin@isc.org> | 2016-12-01 16:29:07 +0100 |
---|---|---|
committer | Marcin Siodelski <marcin@isc.org> | 2016-12-01 16:29:07 +0100 |
commit | 71d45704c0dc4860cee6321130fa950a0e2717fc (patch) | |
tree | 6f82ca8780686472aa972dc3fd0d57ec0c2ca98c /src/lib/process/libprocess.dox | |
parent | [5074] Fix doxygen refs after migration to isc::process namespace. (diff) | |
download | kea-71d45704c0dc4860cee6321130fa950a0e2717fc.tar.xz kea-71d45704c0dc4860cee6321130fa950a0e2717fc.zip |
[5074] Split developer's documentation of CPL and D2.
Diffstat (limited to '')
-rw-r--r-- | src/lib/process/libprocess.dox | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/lib/process/libprocess.dox b/src/lib/process/libprocess.dox new file mode 100644 index 0000000000..2ebeef9e67 --- /dev/null +++ b/src/lib/process/libprocess.dox @@ -0,0 +1,181 @@ +// 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" + +*/ |