BIND 10 #1331: Extend the ZoneUpdater class to support adding diffs

BIND 10 Development do-not-reply at isc.org
Fri Nov 11 04:59:56 UTC 2011


#1331: Extend the ZoneUpdater class to support adding diffs
-------------------------------------+-------------------------------------
                   Reporter:         |                 Owner:  jinmei
  jinmei                             |                Status:  reviewing
                       Type:  task   |             Milestone:
                   Priority:  major  |  Sprint-20111122
                  Component:  data   |            Resolution:
  source                             |             Sensitive:  0
                   Keywords:         |           Sub-Project:  DNS
            Defect Severity:  N/A    |  Estimated Difficulty:  4
Feature Depending on Ticket:         |           Total Hours:  0
        Add Hours to Ticket:         |
                  Internal?:  0      |
-------------------------------------+-------------------------------------

Comment (by jinmei):

 '''general/design'''

 - I personally think we should notify the caller of an explicit
   failure if `journaling` is true while the underlying data source
   doesn't support it.

   We should eventually support the capabilities (there's a ticket),
   and once it's supported the application will be expected to first
   check the capability of the data source and set 'journaling'
   accordingly.  (otherwise, things like dynamic DNS won't work
   correctly if, for example, the underlying data source is volatile
   like writable in-memory without a persistent journal system; the
   application would at least rely on the journal to be stored in a
   persistent storage and return a successful response to a dynamic DNS
   update request once `updater.commit()` succeeds.  If the underlying
   data source actually doesn't support it and simply ignore the
   mismatch, an unexpected thing will happen due to e.g. power
   failure).

   With this scenario in mind, the application shouldn't even try to
   use journaling unless it knows it's supported, and, if some strange
   reason `addRRset()` or `deleteRRset()` fails due to diff handling
   failure even the capability check suggests it's supported, the
   application should actually know that.   At the very least I believe
   we should log the event here
 {{{
             // Don't fail if the backend can't store them
             catch(const isc::NotImplemented&) {}
 }}}
   Silently discarding an internal failure is generally not a good
   practice.

 - I'm not sure if we should allow this flexibility: "When the
   journaling is true, it *might* require that the following update be
   formated as IXFR" (as documented in client.h), and I'd rather
   suggest it be required without may/might.  Unless/until we have a
   smart data source backend that can automatically figure out the
   correct ordering internally *and* the application selectively wants
   to use that particular data source, this "may" will simply increase
   the possibility of giving a false sense of flexibility to
   applications, which subsequently leads to bugs.

 - As for changelog, I personally don't have an opinion, but
   considering Jeremy wanted to have a changelog entry for #1329
   (which is even more invisible for most users/developers than this
   one), I suspect he'd also want to have it for this task.

 '''zone.h'''

 Maybe in the class description, I suggest adding a reference to
 `DataSourceClient::getUpdater` for the meaning of "IXFR sequence".

 '''database.cc'''

 I've not found any substantial issues (except for things related to
 the higher level design).  There are some things to discuss though:

 - while quite straightforward, I'm afraid that addRRset() and
   deleteRRset() are now getting bigger and decreasing readability.
   I propose something like the attached diff.  This patch actually
   contains one (unrelated) bug fix: reject an empty RRset at an
   earlier point of validation; in the previous code if an empty RRset
   is passed and rejected by other validation check, `RRset::toText()`
   would cause another disruption.

 - 'rdata::' could be omitted here:
 {{{
             serial_ =
                 dynamic_cast<const
 rdata::generic::SOA&>(it->getCurrent()).
                 getSerial();
 }}}
  (there are two such cases)

 - need a space after `catch`:
 {{{
             // Don't fail if the backend can't store them
             catch(const isc::NotImplemented&) {}
 }}}
   - also, I've been noticing style inconsistency on whether to place
     catch in the same line of the closing brace for try.
   - but in this particular case I'd rather not catch the exception here
     in the first place as already commented.

 - `Unexpected` doesn't seem to be an appropriate exception here:
 {{{
         isc_throw(isc::Unexpected, "Update sequence not complete");
 }}}
   This exception was generally intended to be used for internal
   unexpected events.  In this case this is basically an application
   bug, so we should use something else.  Maybe abusing `BadValue` even
   though it's not about the parameter, or introduce something like
   `BadOperation`, or some new data source specific exception.

 '''database_unittest.cc'''

 - I've fixed a build error on my system (actually I was surprised it
   compiled on other systems) and pushed it.  commit 6da32ea.

 - This code seems to be a bit cryptic to me:
 {{{
         for (size_t i(0); i < DatabaseAccessor::DIFF_PARAM_COUNT; ++ i) {
             data_equal = data_equal && (data_[i] == other.data_[i]);
         }
 }}}
   While I generally love the elegance of a concise statement, this
   particular one made me use more brain cycle to understand, perhaps
   because it's used in the context of traditional procedural style.
   While it may look dumb, I'd rather prefer something like this:
 {{{
         for (size_t i(0); i < DatabaseAccessor::DIFF_PARAM_COUNT; ++ i) {
             if (data_[i] != other.data_[i]) {
                 data_equal = false;
                 // we could even break here;
             }
         }
 }}}
   If you really want to keep the original style, I won't fight against
   it further, but I'd at least suggest adding redundant parentheses
   for readability:
 {{{
             data_equal = (data_equal && (data_[i] == other.data_[i]));
 }}}

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


More information about the bind10-tickets mailing list