BIND 10 #404: serialize RDATA for in memory data source
BIND 10 Development
do-not-reply at isc.org
Wed Apr 13 08:44:29 UTC 2011
#404: serialize RDATA for in memory data source
-------------------------------------+-------------------------------------
Reporter: jinmei | Owner: jinmei
Type: task | Status: reviewing
Priority: major | Milestone:
Component: data | Sprint-20110419
source | Resolution:
Keywords: | Sensitive: 0
Estimated Number of Hours: 0.0 | Add Hours to Ticket: 0
Billable?: 1 | Total Hours: 0
Internal?: 0 |
-------------------------------------+-------------------------------------
Comment (by jinmei):
Replying to [comment:20 vorner]:
> > It's quite likely to be non portable (or non compatible) at the binary
> > level when we change the STL implementation (even the debug/normal
> > modes of STLPort are incompatible; for example, we'd have to build and
> > use gtest with the same mode of STLPort). Basically, I want to
> > minimize the risk of breaking the compatibility unless there's a
> > strong need to expose it. I admit we are already breaking this level
> > of compatibility in various places of our code, but if we use the fact
> > as an excuse to break it further, it will be more and more difficult
> > to restore the compatibility when if and we want to do that.
>
> I'd really be worried to go that way, it really complicates matters a
lot ‒ we wouldn't be able to put anything except basic types into the
headers, not even a shared pointer. This kind of thing is usually solved
by distro maintainers anyway. So, maybe it's a thing we should bring up to
some call? Or, was it already discussed sometime?
I don't think the incompatibility like the one between debug/normal
modes of STLPort will be taken care of by the distro. As for the
call/previous discussion, we've discussed things related to this topic
time to time, but as far as I know we don't really have a clear
consensus about how much we'd allow non basic types to be in public
interfaces.
I'm happy to raise this project wise, but I'm a bit pessimistic we can
have a consensus. For this specific case, as you seem to want to
avoid hiding buffer quite strongly, and as I have to admit it wouldn't
be very convincing to insist on this case while leaving many others,
I'm okay with leaving the decision on this point to you.
> Replying to [comment:18 jinmei]:
> > Replying to [comment:15 vorner]:
> > - Also as I said, I'd still hide the buffer using pimpl at the moment.
>
> Well, there are actually two issues on that. [...]
>
> So I'm little bit reluctant to do that. Is it about the binary
compatibility as well?
Yes, that's the same discussion. I simply repeated it as a summarized
specific point to the branch code itself. See above.
> > - In general I don't like to have a non private member variable unless
it's absolutely necessary (just as many C++ books suggest), [...]
>
> Again, what good does it bring? Because anybody is able to fully
overwrite the buffer with the write* methods, extend it, shrink it, etc.
So it doesn't bring any protection of integrity. It only complicates
matters for whoever is writing the writeName() function. The rule in
whatever book is rule of thumb, that you don't want just anybody being
able to dig in your guts. This doesn't apply here, since everybody is
already able to do so (and, by definition of what the class does, must
be). Or do I miss some benefit here?
My main concern in this context is to ensure the (larger) flexibility
of changing the internal representation before many other clients,
hopefully third party ones, relies on the public interfaces. Once
someone starts relying on the fact that the backend of MessageRenderer
is OutputBuffer, we won't be able to change that without breaking
compatibility of that deployment. It's true that it's not a problem
today, and, if we are lucky (or unlucky that no one else is interested
in using our APIs) this may never be an issue in future. But exactly
because it's not an immediate threat we tend to underestimate the
risk, and will only regret the decision when the risk is realized and
it's too late.
I understand it's a tradeoff between that kind of robustness and
complexity due to more indirections. I also understand when there are
many public methods that access the internal data it can effectively
mean exposing the data itself. But, in this case, taking these into
account I still prefer publishing the internal data representation.
Like I said in the above paragraph, I understand it's a controversial
point and different people may have different opinion. If you still
don't like my suggestion, I propose bringing this to the dev list and
resolve the conflict consensus-basis.
> > - [comment] This is an off topic for this ticket, but I've been
> thinking it makes more sense to hide the output buffer inside the
> (Abstract)MessageRenderer [...]
> It does make sense in the terms of clean design. On the other side, it
might make one optimisation a little bit harder ‒ currently, it is
possible to reuse the same buffer to render many messages. Maybe it would
be possible to reuse the whole renderer, though.
MessageRender should also be able to be reused. In fact that was my
original intent.
> Anyway, could I propose that we take the lazy approach, make a
> ticket or comment at the interface and leave it as it is until the
> change brings any advantage?
That's fine. In general I agree we should limit the scope of
individual tickets.
> > '''rdatafields.h'''
> > - I don't understand the point of changing the return type of
getFieldSpecData(). Which specific alias problem does the change try to
solve?
>
> Thinking about it once again, I was wrong. The problem would be if
anybody tried to access the data by a pointer to something different than
`char`, `FieldSpec` or `Type/uint16_t` (depending on the part of data
accessed). So, in that sense, `void *` is incompatible with the data,
meaning that you can't access the `void` pointed to because of aliasing
rules. However, no one can really access `void`, so it's not an issue.
Okay.
> So I might return it back to `void *`. However, thinking about it, why
we returned `void *` in the first place, when the docs say it can be
type-casted to `FieldSpec`? In that sense, the API seems inconsistent,
since `void *` usually describe „typeless unknown data“. Wouldn't
returning a `FieldSpec *` make more sense?
Hmm, good point. I don't remember what I exactly thought about the
interface consistency when I first wrote the original code, but my
general intent is to treat the exposed data as opaque as possible.
So, if it doesn't break other part, it will probably make more sense
to change the second constructor of RdataFields so that it takes void*
instead of FieldSpec* (and internally convert it to FieldSpec* using
cast). And, in that case, it may also make sense to use the actual
data length rather than the number of spec's.
> Sorry for disagreeing so much, but I can't help myself feeling it
differently.
No worries. I understand many of the above points are controversial
where people's opinions may vary.
--
Ticket URL: <http://bind10.isc.org/ticket/404#comment:21>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list