From: Marcin Siodelski Date: Thu, 1 Dec 2016 15:29:07 +0000 (+0100) Subject: [5074] Split developer's documentation of CPL and D2. X-Git-Tag: trac5046_base~1^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=71d45704c0dc4860cee6321130fa950a0e2717fc;p=thirdparty%2Fkea.git [5074] Split developer's documentation of CPL and D2. --- diff --git a/doc/devel/mainpage.dox b/doc/devel/mainpage.dox index 61a73c57af..c3f8aa772a 100644 --- a/doc/devel/mainpage.dox +++ b/doc/devel/mainpage.dox @@ -71,8 +71,10 @@ * - @subpage dhcpv6SignalBasedReconfiguration * - @subpage dhcpv6Other * - @subpage dhcpv4o6Dhcp6 + * - @subpage libprocess + * - @subpage cpl + * - @subpage cplSignals * - @subpage d2 - * - @subpage d2CPL * - @subpage d2ProcessDerivation * - @subpage d2ConfigMgt * - @subpage d2NCRReceipt diff --git a/src/bin/d2/d2.dox b/src/bin/d2/d2.dox index d4fede4021..518898e5d5 100644 --- a/src/bin/d2/d2.dox +++ b/src/bin/d2/d2.dox @@ -1,4 +1,4 @@ -// 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 // 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. sometimes through a small chain of typedefs. These typedefs are shown for 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: - - { "": {} } - - 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 D2's core application classes are DDNS-specific derivations of the CPL as show diff --git a/src/lib/process/Makefile.am b/src/lib/process/Makefile.am index 58a3639e80..3a85a7a0bd 100644 --- a/src/lib/process/Makefile.am +++ b/src/lib/process/Makefile.am @@ -30,7 +30,7 @@ spec_config.h: spec_config.h.pre BUILT_SOURCES = spec_config.h process_messages.h process_messages.cc # 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 CLEANFILES = *.gcno *.gcda spec_config.h process_messages.h process_messages.cc s-messages 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: +D2 Design. + +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: + + { "": {} } + + 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" + +*/