[Xorp-hackers] XRL/Thrift: using Thrift to talk to XORP processes (future)
Bruce Simpson
bms at incunabulum.net
Mon Nov 2 10:34:48 PST 2009
A few words on using Thrift externally to talk to XORP processes, and
what shape that is likely to take.
* The intention behind the current effort, is to replace XRL with the
Thrift protocol.
* In Thrift-speak, every XORP process advertising a service, will have
the equivalent of a TServerSocket endpoint open for reaching that
service and sending it RPC requests.
* This will use the TFramedTransport with the TBinaryProtocol.
There are going to be some issues with this in the beginning which need
to be resolved. Rather than try to resolve them myself upfront, I'm
going to document them as we go along.
* If you look at the tutorials shipped with Thrift, they're very simple:
* The Calculator client example opens a single socket to a known
Thrift service port.
* No service discovery (RPC name resolution) is performed.
Now because XORP processes need to participate in the Finder protocol to
discover where the components are (and in some cases, as we've seen,
even communicate with them), it isn't a simple matter of just
instantiating a TSocket as Calculator does.
* It would be unreasonable to expect developers to clone all of the
logic in XrlRouter for naming/discovery, so XrlRouter is still going to
be needed in these situations.
* There may be situations where developers need to implement an XRL
target in their 3rd party code, without necessarily getting involved in
the sync/async split.
* It is one very constrained scenario where threading could be useful.
* In Thrift clients, as they are currently implemented, calls are
purely blocking (synchronous), but language native.
* However: Thrift's client stubs always pass a 0 sequence number for
their T_CALL messages.
* This is absolutely fine if you only ever have one request in flight
from the client to the server in a session, but it pretty much kills any
possible parallelism or asynchrony.
In XORP's integration of Thrift, we *will* be relying on the ability to
tell requests from the same client apart.
* We could delve into the blob and rewrite it, but we can only do
that if we have control of the transport. We have no such control in the
Thrift libraries as shipped.
* Also if we're using ring buffers, that's gnarly. We would ideally
like to hit a send() or writev() once and be done with it, to avoid
increasing syscall overhead in situations where we need high performance.
* As we've seen, the use of a TCP stream (where in-order delivery is
guaranteed) forces serialization of RPC calls, but it isn't evident at
API level.
* This may break message-oriented transports, and it's difficult to
mix-and-match libxipc's pseudo-async i/o mode with a Thrift client's
sync i/o mode without tripping up over it.
* The assumption in their programming model seems to be that threads
will be used in a Java-like way: ie. cheap, don't share much state, and
what they do is explicitly 'synchronized'.
* So we'd have to be very careful about how libxipc gets entered. The
code is not currently thread-safe.
* So what we'll probably have to do, is support one model or the other,
but not both at once.
* Add a blocking API for service lookup to XrlRouter -- we can't rely
on the EventLoop being run whilst we're in blocking Thrift APIs.
* The 0 cseqid is only really an issue if we have more than one RPC
in-flight on the same transport from the same client.
* Either force clients to build their own TTransport to connect to it,
or add a hook to XrlRouter to place the I/O streams in a blocking mode.
Alternatively, we could add an API to Thrift internally to request a new
cseqid for each outgoing request, but that is something which needs to
be discussed with the Thrift developers, through the Apache JIRA process.
thanks,
BMS
More information about the Xorp-hackers
mailing list