Reputation: 71
I'd like to create several services, and I want to use them with different identifiers. So I mean :
I've got a Users and Projects service . I want to use these at the same time.
I mean I can add more 'services' to the "handlermap" on xmlrpc.
http://ws.apache.org/xmlrpc/server.html
phm.addHandler("Users",
Users.class);
phm.addHandler("Projects",
Projects.class);
I would like to do the same in the thrift.
Here is a simple example : test.thrift
typedef i64 UserId
struct Bonk
{
1: string message,
2: i32 type
}
struct Insanity
{
1: map<Bonk, UserId> userMap,
2: list<Bonk> xtructs
}
service ThriftTest
{
void testVoid(),
string testString(1: string test),
byte testByte(1: byte test),
i32 testI32(1: i32 test),
i64 testI64(1: i64 test),
double testDouble(1: double test),
list<map<i32,i32>> testMap(1: map<i32,i32> test),
map<string,string> testStringMap(1: map<string,string> test),
set<i32> testSet(1: set<i32> test),
map<i32,map<i32,i32>> testMapMap(1: i32 test),
map<UserId, map<i32,Insanity>> testInsanity(1: Insanity argument)
}
Then I create an implementatino, then add it to the instance of TServer .
Users.Processor users_proccesor = new Users.Processor(New UsersImpl());
Projects.Processor project_processor = new Projects.Processors(new ProjectsImp());
// I would like to add Users and Projects
ThriftTest.Processor prc = new ThriftTest.Processor(new ThiftTestImp());
TServerTransport serverTransport = new TServerSocket(9090);
TServer server = new TSimpleServer(new Args(serverTransport).processor( prc ));
And here's my big problem, I can't add multiple instances of the server.
Thank you for your help in advance.
Upvotes: 7
Views: 5462
Reputation: 13411
Multiplexed Services (in essence that's what you want to do here) are being integrated right now. There are already patches for a number of languages available, either already accepted or in the process of being reviewed.
https://issues.apache.org/jira/browse/THRIFT-563 is a good place to start.
PS: Reviewers and contributions are welcome ;-)
Upvotes: 7
Reputation: 6418
RPC invocation is transmitted over the wire in TMessage structure that doesn't have 'targetService' field. So there's no straightforward way to bind several services to a single port without adding this field to TMessage and recompiling thrift.
It's possible to do a hack by implementing custom TServer similar to TSimpleSever (or any other TServer).
Server should read target service in the loop and get corresponding processor:
...
inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);
do {
String target = inputProtocol.readString();
processor = processorFactoryMap.get(target).getProcessor(client);
while (processor.process(inputProtocol, outputProtocol));
...
Client should prefix each message with target service string. This can be done by wrapping TBinaryProtocol in a custom protocol:
public void writeMessageBegin(TMessage message) throws TException {
wrapped.writeString(target);
wrapped.writeMessageBegin(message);
}
The main disadvantage of this approach is losing interoperability with other clients. So, probably it's better either to start two different TServers on different ports, or define all methods in a single thrift service, and then delegate invocations to appropriate handlers.
Upvotes: 5