Todd Lipcon wrote:
First, some RPC mechanisms support the idea of objects; instances of
interfaces that can be specifically addressed. If we, for example,
were to create an interface to administrate virtual servers for
Apache, it is IMHO much cleaner to
$object = $remote->getObject("/virtual.hostname");
$object->setServerAdmin("blahblah");
than
$remote->setServerAdmin("/virtual.hostname","blahblah");
(you'd have a bunch of methods, all of which start with the vhost
parameter).
There's currently no way of doing this, as not all of the languages
that thrift supports have the concept of objects.
The way I'd recommend doing this is:
$hostRef = $remote->getObject("/virtual.hostname");
$remote->setServerAdmin($hostRef, "blahblah");
where $hostRef is an i64 that's unique and non-sequential.
It should be straightforward enough to implement this using a
hashtable of objects on the server and using a thin procedural layer
to talk to an OO instance on the backend.
It is straightforward enough, but it feels a bit like doing OO without OO.
Even if all the languages Thrift supports don't have the concept of
object, they do need state information stored. Otherwise every function
call would need to specify the transport, protocol and full destination.
So however that information is stored with the client "object", we could
also store a object id or path.
Path information is already present for the HTTP transport; you can
extract it from the URI used. The problem is finding something similar
to use for the binary protocol, preferably without having each instance
of the interface listen on a different port.
Looking a bit at the binary protocol, it seems this can be implemented
without altering the protocol specification; instead of sending the
function name "setServerAdmin", you send
"virtual.hostname/setServerAdmin". So it's doable in a
backward-compatible fashion, but it will require a bit of work.
Second, it often is very useful to know where a request came from and
how we got here. For example, it might be beneficial to limit the
amount of requests per second per source IP, and for that we'd need
the context the call came through. This could also be used to cache
data on a per-client basis, and is useful for logging. Is there an
easy way to get this from inside the interface implementation in your
program?
To implement this you'd have to subclass the server. I'm not very
familiar with the cpp bindings, but I don't imagine it would be
extremely difficult.
Looking at the generated cpp code, there doesn't seem to be any
propagation of transport or protocol information. This is generally a
good idea, except I sort of need it ;) Changing this would seem to
require changing the thrift-to-cpp compiler, which is likely quite a lot
of work. I can't simply override parts of the server and set a global
variable; doing so would not be thread-safe.
Are these issues something even worth looking at, or are they way
outside the usage scenarios for Thrift?
Best regards,
Thorvald