BIND 10 #1068: support writability in the new data source API

BIND 10 Development do-not-reply at isc.org
Wed Sep 7 01:07:52 UTC 2011


#1068: support writability in the new data source API
-------------------------------------+-------------------------------------
                   Reporter:         |                 Owner:  jinmei
  jinmei                             |                Status:  reviewing
                       Type:  task   |             Milestone:
                   Priority:  major  |  Sprint-20110927
                  Component:  data   |            Resolution:
  source                             |             Sensitive:  0
                   Keywords:         |           Sub-Project:  DNS
            Defect Severity:  N/A    |  Estimated Difficulty:  7.0
Feature Depending on Ticket:         |           Total Hours:  0
        Add Hours to Ticket:  0      |
                  Internal?:  0      |
-------------------------------------+-------------------------------------

Comment (by jinmei):

 Replying to [comment:15 vorner]:

 > First, notes about the interface ‒ I think it might be useful to be able
 to add and remove zones in backend-agnostic way (and maybe as an atomic
 operation with filling it with data). For example b10-loadzone could use
 it. But it might be out of the scope of this ticket.

 I was aware of the need (and the lack in the current implementation)
 for adding/removing zones.  I also think we should move the
 functionality of creating a new DB outside the basic responsibility of
 the accessor (in fact it does something beyond the scope of its
 work).  But as you thought I think these extensions/cleanups would
 better be deferred to later plans.

 > Then, of course, few notes about the code:
 >  * {{{The underlying realization of a "transaction" will defer for
 different}}} ‒ you mean „differ“ or that we defer it to the different
 implementation?

 Ah, good catch.  Yes, it should be "differ".  Fixed.

 >  * This isn't something that would be wrong in any way and it is
 possibly only style matter, but I'm just curious about the rationale about
 it ‒ the DatabaseUpdater's methods (addRRset, deleteRRset, commit) live
 outside the class definition. Why is it so? I think that the original
 reason for being able to have method implementation outside the class
 exists because of class lives in header file and the code shouldn't, but
 that doesn't apply as both are in the source in this case.

 It's a subjective decision (or preference).  I wanted to keep the size
 of the class definition reasonably concise so that the entire
 definition can be browsed at a glance (e.g., without scrolling on a
 reasonably larger size of window).  So I moved some relatively larger
 methods outside the definition.  On the other hand I admit it may look
 inconsistent as some others are still in the class definition even if
 they are super simple ones like getFinder(), and the conciseness
 argument may not be that convincing anyway if we want to provide more
 inline comments.  So this is not a strong preference.

 >  * Should addRRset take the attached signature into account as well?
 (eg. issue the th addRRset on the signature if it's present, or something)

 May or may not be.  As we briefly talked before in a different context,
 I personally wanted to revisit the design of how to represent signed
 RRsets, and would hesitate to make the interface "too convenient"
 until then (including the possible conclusion of not changing the
 design).

 As far as I can see we shouldn't need to allow this mode in the
 meantime, so I believe we can safely defer it to later discussions.
 But to prevent accidental misuse I added explicit checks so that
 an attempt of adding/deleting RRset + RRSIG RRset will result in an
 exception (for the delete case it would actually make sense to
 prohibit it).

 >  * Why are add_columns_ and del_params_ object-level variables? It would
 be enough for them to live only inside the methods they are used in,
 wouldn't it?
 >  * Related to this: In case the RRSIG isn't the last thing added through
 this updater, any subsequent RRs will have the same ADD_SIGTYPE column.
 Should it be reset afterwards to empty string?

 Ah, good point.  As for why as member variables, they were originally
 vectors, and I wanted to avoid the overhead of constructing them
 every time the methods are called (but even then it might be a bad
 attempt of premature optimization - after all these methods are not
 expected to be performed in a very performance sensitive path).  Now
 they are plain arrays, it makes even more sense to define them locally
 in the methods.

 As for SIGTYPE, yes, you're right, the original code had a bug.

 I updated the code to define the arrays as method local, and (although
 it's now pretty obvious to be safe from the code) added a test case
 that would have identified the bug in the previous version.

 >  * Can the destructor of the accessor throw? If so, the commit would
 have a problem ‒ the committed_ would stay as false and the class will
 call rollback on the (already destroyed or partly destroyed) accessor.
 Should the {{{committed_ = true}}} be moved above the
 {{{accessor_.reset()}}}?

 Hmm, good point.  I'd call it a bug if the destructor of an accessor
 ever threw (it would cause other serious effects even if not here),
 but since the accessor API is public and we expect external developers
 to write their own accessors possibly with bugs, it would be better to
 be as proactive as possible.  So I changed the code as suggested.

 >  * A style issue ‒ the commit and rollback are handled from within the
 updater. Should startUpdateZone be called from the DatabaseUpdater's
 constructor instead of outside the class, because of consistency?

 I have no strong opinion on for/against the consistency per se, but it
 wouldn't be that straightforward in this case.  According to the
 current API design we need to return a NULL pointer if the specified
 zone doesn't exist.  This condition is checked via the return value
 from startUpdateZone(), so if we included the call in the
 DatabaseUpdater constructor, we'd need to have it throw for
 non-existent zone, catch it in getUpdater (and differentiate it from
 other errors resulting in the same exception type), and convert it to
 a NULL pointer.

 Since the DatabaseUpdater() class details are purely internal to the
 database.cc implementation, I think we can be a bit more flexible on
 the consistency on the interfaces.  So, right now I've not modified
 the code on this point, preferring implementation simplicity.

 >  * This is probably out of the scope of this ticket, but shouldn't the
 getUpdater of in-memory propagate the call to the underlying data source
 instead of calling NotImplemented in the long term? If so, maybe there
 should be a note/comment about it?

 Possibly, or possibly not.  Right now it's not clear how we relate the
 in-memory client to its underlying databases (or some other backend
 storage) and how applications that need to get access to the
 underlying storage directly (e.g. whether it's via the in-memory
 interface or not).

 >  * The protected ZoneUpdater constructor is not needed. If anybody tries
 to create instance of it, the compilation will fail because it has pure
 virtual methods.

 I think we discussed this before - in the current implementation,
 that's true, but I personally prefer making this explicit.  IMO it's
 fragile to rely on the existence of a pure virtual method (without a
 definition) for this purpose; we may want to revise the interface to
 provide the default implementation at the base class level.  We could
 still provide the default with keeping it pure virtual by defining the
 pure virtual function and having derived classes call it explicitly,
 but we are not currently using that practice.  Also, while the same
 argument could apply to the constructor (we might want to make it
 public for some reason), I believe it's much less common in practice.

 If you still don't like the redundancy in explicitly declaring and
 defining the constructor or do want to have a unified policy, I'm okay
 with having a discussion project wide.  Right now I'm keeping the
 current code.

 >  * Would it help to have a test for „bigger“ transaction (like more adds
 and deletes during one transaction)?

 Good idea.  Added a new test named compoundUpdate.

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


More information about the bind10-tickets mailing list