Andrew Stitcher wrote:
- If the customer knows they want TCP_NODELAY, it's not obvious that means
"minimizeLatency". As soon as we document the relationship, our "abstraction"
cease to be abstract.
But they'll never want TCP_NODELAY just the effect (they think) it
brings, which is minimise the latency of my messages through the AMQP
stack and network. As I pointed out in IRC I think that TCP_NODELAY used
without thought can make the latency worse not better.
Agreed, but customers that know TCP will be inclined to want to try these
things. Unless/until we have comprehensive transport-independent policies that
cover everything you might do with TCP options, allowing people to set TCP
options in a portable way seems like a good compromise that will
a) allow customers (and ourselves) to experiment, which may turn up useful
info.
b) keep customers who want to experiment happy, giving us time to develop
genuinely abstract transport-independent policies that are not just knee-jerk
reactions to persistent requests for specific TCP options.
The following is a fine implementation, and would work just as well if we are
talking about the more abstracted properties as well.
Agreed - that was my thinking. Totally generic policies that we believe will
apply to any transport could go on ConnectionPolicy as virtual functions that
get overridden by specific policies. We could also define transport "families"
with similar characteristics as intermediate base classes, e.g.
StreamConnectionPolicy or PacketConnectionPolicy.
However I think the first step is to define leaf policies for TCP, with SSL and
infiniband following closely. That gets us off the hook in the short term with
users who want to experiment with TCP options but leaves it open to us to build
abstractions above that as we get a better understanding of the kind of policies
that apply across transports. Indeed being able to easily tweak
transport-specific policies will probably help us in our performance experiments
as well.
If we go this route we should also define broker configuration for policies,
some consistent naming scheme generated from the policy classes, e.g.
--policy-tcp-nodelay
class ConnectionPolicy {}; // Abstract base for connection policies.
class TcpConnectionPolicy {
bool TCP_NODELAY;
.. etc whatever we want to expose
}
class Connection {
void applyPolicy(ConnetionPolicy&)
}
TcpConnectionPolicy p;
p.TCP_NODELAY = true;
myConnection.applyPolicy(p);
The semantics here are that IF myConnection is indeed a TCP connection, the
policy will be applied, if not, it will be ignored.
This supports the case where the users _knows_ they are dealing with TCP and
_knows_ the TCP specific options they want. However the code remains portable
and valid if it is someday run on a non TCP connection - the TCP policy is
simply ignored.
We could extend this notion to provide generic policy options on policy base
classes, or even to categorize transports into families with common options. I
don't think we're there yet, but for now it's a good solution to setting TCP
options in a portable way.