Dan Di Spaltro wrote:
I couldn't find a Jira ticket for this feature and wasn't sure if
anyone (Ross?) was still actively trying to develop it.
Is there any work being done on this front?
Not as far as I know. It would be very useful to have, so if you plan to
write one, that would be absolutely great.
Thrift is an object-oriented framework, so a bit of adaptation would be
needed to get it to talk to plain old C.
The thing is, the 'libthrift' library for C++ contains most of the
components needed to talk to a Thrift service or to build one
(TTransport, TProtocol, TServer -- but not TProcessor) in C++.
You could start from scratch, or you could re-use the existing C++
library, provided you can satisfy the link requirements for a C++
library. Starting from scratch would essentially mean reimplementing the
whole framework for C, or only implementing a specialized part of it.
A quick look suggests there are no static constructors to worry about,
so dynamic linking of C against the C++ library should be OK -- although
you may also need to pull in the dynamic C++ runtime for the same
compiler as you compiled 'libthrift' with.
At the end of the day, all the C++ generator is doing, is generating
language-level bindings which slot into the rest of the framework.
If you were to choose to base off the existing C++ libthrift library,
here are some ideas:
A good starting point might be to write an Adaptor model of
TProcessor, which wraps a C-style function dispatch table, keyed by the
method name as an ASCII string. The C++ bindings use a std::map for
this, which is usually implemented as a red-black tree. This does allow
for modifying the map at runtime -- it gets built in the
serviceProcessor constructor -- but nothing makes use of that.
For plain old C, a hash table would do the job there just fine. The
TProcessor wrapper needs to get passed a handle to your hash table so
process() can do its job; at this point you might be better off
parsing/writing the wire protocol in here just the way the C++ bindings
do...
A plain C interface to instantiating all of the required components
would be needed. Memory management could get tricky.
The service_method_(args|pargs|result|presult) structures generated in
the C++ bindings are fully fledged C++ objects, and used for marshaling
the service call parameters themselves (they will call TTransport).
Marshaling collections would be really tricky. C has no notion of high
level containers -- it's worth raiding FreeBSD for its LIST/TAILQ/RB
macros, those would let you build Thrift style lists/maps relatively
quickly (they are intrusive C macros, a bit like templates).
Anyway, that's just a brain dump on a Monday afternoon.
cheers,
BMS