On Mon, Nov 19, 2012 at 5:26 PM, roger peppe wrote:
The fact that passing a nil channel results in a new channel
with a buffer size of 100 is asking for trouble AFAICS.
Usually the caller will know how many requests they're
issuing and so can size the channel accordingly - 100 is
either way too many or perhaps too few.
Too few it is not, typical zone has two (reasonable number) name
servers. 100 items is an overkill on the safe side, but it costs only
some kilobytes, i.e. it's comparable to the size of the buffers which
have to be used for the communication anyway. And you can alway pass
in a smaller (shorter) channel if you don't want the default size for
any reason. However, 20 instead of 100 would
There is probably some misunderstanding here. The message exchange is
for one specific DNS query. If the _same_ query is to be sent by the
client to more than one server (typically 1 to 4, the average being
less than 2) under certain circumstances then those 2 (sometimes 3 or
4) queries are sent to different servers and the client has the option
to collect all the responses in one channel only. But only if she wish
to do so. It's all configurable in the client's code.
Different queries for different questions are not typically reported
back on the same channel (no good reason for that). Walking the DNS
tree is mostly not an async process at all (at least not as depicted
in the RFCs). The exception to this rule happens when a name server
provides an authority without glue records. Then it is (see the RFC
again), legitimate, or even reasonable, to search for them in
parallel. Again, usually/typically two questions are sent concurrently
in that situation.
The former is just inefficient - the latter is potentially leaky. ???
I'd suggest that:
ch := make(msg.ExchangeReply, N)
msg1.GoExchange(conn1, limit, ch)
msg1.GoExchange(conn2, limit, ch)
...
msgN.GoExchange(connN, limit, ch)
is more natural and more obvious to the reader.
You can write exactly that, it _is_ supported by `GoExchange`. BTW,
the confusion perhaps steams from that only the mechanism was
suggested (the channel "chaíning" by the functions), not the
implementation. Actually the "msg" package is a very low level one.
Normally DNS clients use the "resolver" package instead. The "msg"
package contains factored out stuff common to a DNS client and a DNS
server, roughly said.
However, even better, leaving all the automatic concurrency stuff out of the
package would be more in keeping with Go's usual style. We don't have
http.GoGet or net.GoDial.
You're right, I would not write that in the standard library either.
In a specific project's support package it is a matter of preferences.
One usually wants to expose the reusable parts for own/other's
(re)use, but also adds on top of that helpers based on patterns
occurring repeatedly in the client code (and yes, your boss wants the
code no later than week ago). And then you use the exposed helpers and
cannot remove them w/o breaking backwards compatibility.
-j
PS: Also it should be probably noted that the code in question, the
"dns" package was started and written mostly in 2010. For sure I would
today, in my fourth year of Go hacking, design (some) things in a
different way. But one usually doesn't simply later change/break
company's production code only b/c it's not nice (but working ;-)
--