BIND 10 #2376: define LoaderContext class

BIND 10 Development do-not-reply at isc.org
Thu Nov 8 22:28:46 UTC 2012


#2376: define LoaderContext class
-------------------------------------+-------------------------------------
                   Reporter:         |                 Owner:  jinmei
  jinmei                             |                Status:  reviewing
                       Type:  task   |             Milestone:
                   Priority:         |  Sprint-20121120
  medium                             |            Resolution:
                  Component:  data   |             Sensitive:  0
  source                             |           Sub-Project:  DNS
                   Keywords:         |  Estimated Difficulty:  4
            Defect Severity:  N/A    |           Total Hours:  0
Feature Depending on Ticket:         |
  scalable inmemory                  |
        Add Hours to Ticket:  0      |
                  Internal?:  0      |
-------------------------------------+-------------------------------------

Comment (by jinmei):

 Replying to [comment:5 vorner]:

 > It should be ready for review. But I have two concerns about the class:
 >  * Since the operator() can be non-const and the getCallbacks is a const
 >    method, we need the ugly mutable keyword. Return a non-reference? Or
 make
 >    the method non-const?

 Hmm, I made my review comments before reading this, and I pointed out
 related/same point.

 Basically, if we want to allow the callback to modify the originating
 context (such as in `LoaderContext::handleError`), we simply cannot
 `getCallbacks()` a const member function; in the original proposal I
 rather thought the callbacks were stateless and can be const.  I see
 two options:

 - just give up making `getCallbacks()` const.  But in that case, I'd
   like to make the `Callbacks` structure safer (I discussed the issue
   in my own comments below).  Introducing a specific constructor,
   hide error/warn variables as private, and (e.g.) have its user call
   the callback via a wrapper method:
 {{{#!cpp
 struct LoaderCallbacks { // to this end this should probably be a class
 public:
     void error(source_name, line, byte, reason) {
         error_(source_name, line, byte, reason);
     }
 private:
     Callback error_;
 };
 }}}
 - force the callback user to keep the const semantics.  For example, I
   think it possible to change `LoaderContext::handleError` so it will
   be a static member function of `LoaderContext` that takes a mutable
   `LoaderContext`:
 {{{#!cpp
 class LoaderContext : public isc::dns::MasterLoaderContextBase {
 public:
     static void handleError(LoaderContext* context, source, line, byte,
 reason) {
         LOG_ERROR(logger,...);
         context->ok_ = false;
     }
 };
 }}}
   Technically, We are here, though, as the callback functor would
   actually holds a mutable reference to `this`, and `getCallbacks()`
   implicitly passes the mutable `this` even if it's defined as a
   const member function of `this`.

 >  * This is another glue class that does nothing :-(. Not that I'd know
 what to
 >    do with it at this stage, but it makes the code gradually unreadable.

 I didn't see any readability difficulty in the branch as someone who
 basically knows what we will do with this code in later stages.  I
 think it's a common case of the tradeoff about breaking a specific
 feature into several development tasks, and of the discussion about
 the reasonable "bitable" size of tasks.  I personally don't think this
 one is too small, but as we discussed in the call the other day, in
 future tasks we can discuss it before starting the sprint if someone
 feels a particular task is too small for the overhead.

 '''master_loader.h'''

 - maybe it's even better to define callbacks in a different header
   file (so when it's used in rdata it wouldn't look too awkward).
   but I don't come up with a specific good idea about where, and in
   any case the concept of 'filename' or 'line no.' indicates
   "loading", so probably we simply cannot eliminate the awkwardness
   anyway.
 - is it possible to make error and warning const?  In general, I'd
   like to avoid allowing a user of a class/struct to modify its
   internal members in an arbitrary way.
 - for the same reason, could the return value of getCallback() be
   `const LoaderCallbacks&`?  on a related note, it looks awkward that
   it's a const member function as in its natural implementation the
   corresponding callback should be part of the context in some way,
   at least conceptually.
 - `LoaderCallbacks`: slightly related to the previous point, if "All
   the callbacks must be set" also means they cannot be a null
   function, I'd introduce an explicit constructor and reject bogus
   input (and, of course, such checks on construction isn't useful much
   if the application can freely modify them).
 - I'm not sure if `source_byte` is of any use for error reporting
   purposes.  hmm, maybe to help identify the specific keyword in the
   `source_line` that causes the error?
 - you may want to document the parameter for
   `MasterLoaderContextBase::addRRset()`, although it may look obvious
   from the context and the general description.  Same for the return
   value of `getCallbacks()`.
 - `MasterLoaderContextBase` should have a virtual destructor.
 - `addRRset`: I wonder we might now want to make the parameter
   `ConstRRsetPtr`.  Excluding the old version of in-memory
   implementation, our current implementations shouldn't need to modify
   the given rrset.  On the other hand, since the master loader
   shouldn't need to be able to use the rrset after passing it to
   `addRRset`, it might be more convenient for the user of the loader
   if it can be mutable.  If we keep it mutable, I'd note that
   `MasterLoader` releases the ownership of the rrset on calling
   `addRRset` and won't modify it.  I'd also note that `MasterLoader`
   never gives a NULL pointer.  I'd further note `rrset` wouldn't be
   accompanied with RRSIG (RRSIG `RRsets` will be passed separately in
   a separate call to `addRRset`).

 '''loader_context.h'''

 - general: I'd document possible exceptions for each method, and say
   so if it's exception free.
 - constructor: I'd note `updater` must have been created in the
   "replace" mode (although the context class doesn't check it).
 - `callbacks_`: as discussed in master_loader.h, I guess we might
   revisit the constness of callbacks and of its related methods.

 '''loader_context.cc'''

 - we may want to include the zone name and class in the log messages.

 '''loader_context_test'''

 - not a big deal, but `LoaderContextTest` constructor doesn't have to
   be public (protected is enough)
 - `addRrset` test: shouldn't we refill in expected_rrsets_ before the
   second round of test?

 '''datasrc_message.mes'''
 - do we need quotations for line numbers?
 - in BIND 9, file name and line number are shown in a concise form:
   <filename>:<line_no> I guess such simplified form is better in this
   case in that log messages are generally better to be concise and in
   this case it should be pretty clear what it would mean.  But it may
   be a matter of taste, so I don't push it strongly.

-- 
Ticket URL: <http://bind10.isc.org/ticket/2376#comment:7>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list