Fwd: UpdateMgr asynch IO design for D2

Thomas Markwalder tmark at isc.org
Thu May 9 16:43:49 UTC 2013


Stephen asked that I forward this to the bind10 team.s


-------- Original Message --------
Subject: 	UpdateMgr asynch IO design for D2
Date: 	Wed, 08 May 2013 16:32:39 -0400
From: 	Thomas Markwalder <tmark at isc.org>
To: 	dhcp-team at isc.org <dhcp-team at isc.org>



Hello all:

One of the more glaring todo's was to iron out a plan for dealing with
D2's asynchronous IO and whether it would be single-threaded or
multi-threaded.  The following documents my proposed basic design for this:

(I suppose this ought to be on Wiki....)

Thanks,

Thomas



Introduction:
=============

This is the overall design for D2 and how it will handle its asynchronous,
event driven nature.

Background:
===========

A review of the asynchronous events that D2 must handle yields the
following
list:

1. Name change request messages from DHCP servers and/or a house-keeper
process.
    When messages are received:
         a. They need to be added to the queue as NameChangeRequests.
         b. D2 must be made aware that the Queue has entries.

2. DNS message exchange events from DNS update exchanges with DNS servers.
    Each transaction can consist of multiple sends and receives. Each send
    and receive outcome amounts to an event.  These events are used to move
    each transaction through its state machine.  At points in which the
    transaction must wait for IO, control should be yielded.

3. Control Events - primarily "shutdown" but there could be others?

4. Completed Transactions - While not an event per se, D2 does need to
monitor its list of transactions, for those that have completed.

This discussion is based on the assumption, that D2 should be able to
carry out
more than one DNS update at a time.

The design should reuse existing libraries where possible and to that end
the DNS UPDATE exchanges will use the asiolink library to carry out
socket IO.

In addition, the NameChangeIPC will be socket-based rather than use
boost::interprocess::messagequeue. This will allow the use of the asiolink
library for handling the receipt of name change request messages as well.
This unifies the asynchronouse IO and event callback mechanisms for the two
external event sources.

The design is structured such that it can support both a single-threaded
operation as well as a multi-threaded operation.  The two modes of
operation
are described below.


Single-threaded operation:
==========================

In single-threaded operation, the main processing loop performs a single
  "blocking" wait for events from all the event sources.

Since both the NameChangeIPC and DNS exchanges will use asiolink/socket IO,
D2 can use a single asiolink::io_service object to wait for and execute
callbacks for both event sources.

The QueueMgr's NameChangeIPC callback will create NCRs from the packets
received
and add them to the NCR Queue.

For a DNS transaction, its DNS exchange callback(s) will "post" the
appropriate
event to transaction's state machine. This drives the state machine forward
until next IO-wait is reached or the state machine completes.

The D2::UpdateMgr main run loop will look something like this:

     while (!shutdown) {

         // Execute all ready callbacks, or wait for one
         if (io_service.poll() || io_service.run_one()) {

             // One or more of the following has occurred
             //   a. NCR message received and has been queued
             //   b. Pending DNS IO has completed
             //   c. Interval timer expired

             if (QueueMgr->queueNotEmpty()) {
                 // Dequeue next pending request
                 NCR = QueueMgr->dequeue();

                 // Start a new transaction for the NCR
                 instantiate_transaction(io_service, NCR);
             }

             handle_finished_transactions();

         } else {

             // we are here because there is no more work to do
             // somebody stopped io_service, shutdown request likely culprit

         }
     }

To ensure we periodically sweep, an Interval timer will be used to
generate a
ready callback at regular intervals.



Multi-threaded operation:
=========================

As with the single-threaded operation, D2 will wait for and execute
callbacks
for the NameChangeIPC.  QueueMgr runs in the main D2 thread, its
NameChangeIPC
callback will create NCRs from the packets received and add them to its NCR
Queue.

Each transaction, however, runs in its own thread, using its own io_service
object. Its events are never felt by the main thread.  It will wait for and
process its own callbacks, driving itself through its state machine.

The D2::UpdateMgr main run loop remains effectively the same as before:

     while (!shutdown)
     {
         // Execute all ready callbacks, or wait for one
         if (io_service.poll() || io_service.run_one())
         {
             // One or more of the following has occurred
             //   a. NCR message received and has been queued
             //   b. Interval timer expired

             if (QueueMgr->queueNotEmpty()) {
                 // Dequeue next pending request
                 NCR = QueueMgr->dequeue();

                 // Start a new threaded transaction for the NCR
                 instantiate threaded_transaction(NCR);
             }

             handle_finished_transactions();
         }
         else
         {
             // we are here because there is no more work to do
             // somebody stopped io_service, shutdown request likely culprit
         }
     }

Again, to ensure we periodically sweep, an Interval timer will be used to
generate a ready callback at regular intervals.

The only real difference between the two loop's is in the type of
transaction
instantiated.






-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.isc.org/pipermail/bind10-dhcp/attachments/20130509/584227ab/attachment.html>


More information about the bind10-dhcp mailing list