Discussion:
how does a oneway method work with TThreadPoolServer
Parvesh Garg
2017-07-14 08:18:11 UTC
Permalink
Hi,

I have a basic question about how the oneway method called from client work
with TThreadPoolServer. We have a server written in C++ that uses thread
pool server with 4 threads. The client in python connects only once and
keep pushing data to server using a oneway method. Our doubt is will the
server queue the events and process them in a single thread or spawn
multiple threads to take care of each event?

Client is single threaded.

Thrift version is 0.10.0

Here is a glimpse of code showing how the server is configured.

int main(int /*argc*/, char ** /*argv*/) {
boost::shared_ptr<AppServerHandler> handler(new AppServerHandler());
boost::shared_ptr<TProcessor> processor(new AppServerProcessor(handler));

int port_b = 9090;

boost::shared_ptr<TServerTransport> serverTransport_b(new
TServerSocket(port_b));

boost::shared_ptr<TTransportFactory> transportFactory_b(new
TBufferedTransportFactory());

boost::shared_ptr<TProtocolFactory> protocolFactory_b(new
TBinaryProtocolFactory());

boost::shared_ptr<ThreadManager> threadManager_b =
ThreadManager::newSimpleThreadManager(4);

boost::shared_ptr<PosixThreadFactory> threadFactory_b(new
PosixThreadFactory());
threadManager_b->threadFactory(threadFactory_b);
threadManager_b->start();

TThreadPoolServer server_b(processor, serverTransport_b,
transportFactory_b,
protocolFactory_b, threadManager_b);
server_b.serve();
return 0;
}

Happy to provide more details if needed.

Thanks,
Parvesh Garg
Randy Abernethy
2017-07-14 16:03:34 UTC
Permalink
Hey Parvesh,

The C++ Threaded and ThreadPool severs assign a single thread to each
connection. So if you send 10 requests (one way) on a single connection a
single server thread will handle them in order (serially). Even the
nonblocking C++ server handles requests serially per connection (though it
can process tasks from many different connections at once in the task
pool). While not always the most efficient model, this serial per
connection approach guarantees that multiple requests on a single
connection behave like serial function calls (which is the essence of the
RPC model).

Sounds like what you are trying to do (and what one-way half way enables)
is to send async messages to a server that it can process concurrently. If
you want concurrency on a single connections requests the easiest path
(IMHO) is to queue the work to a background thread pool for processing.

Hope this helps,
Randy
Post by Parvesh Garg
Hi,
I have a basic question about how the oneway method called from client work
with TThreadPoolServer. We have a server written in C++ that uses thread
pool server with 4 threads. The client in python connects only once and
keep pushing data to server using a oneway method. Our doubt is will the
server queue the events and process them in a single thread or spawn
multiple threads to take care of each event?
Client is single threaded.
Thrift version is 0.10.0
Here is a glimpse of code showing how the server is configured.
int main(int /*argc*/, char ** /*argv*/) {
boost::shared_ptr<AppServerHandler> handler(new AppServerHandler());
boost::shared_ptr<TProcessor> processor(new AppServerProcessor(handler));
int port_b = 9090;
boost::shared_ptr<TServerTransport> serverTransport_b(new
TServerSocket(port_b));
boost::shared_ptr<TTransportFactory> transportFactory_b(new
TBufferedTransportFactory());
boost::shared_ptr<TProtocolFactory> protocolFactory_b(new
TBinaryProtocolFactory());
boost::shared_ptr<ThreadManager> threadManager_b =
ThreadManager::newSimpleThreadManager(4);
boost::shared_ptr<PosixThreadFactory> threadFactory_b(new
PosixThreadFactory());
threadManager_b->threadFactory(threadFactory_b);
threadManager_b->start();
TThreadPoolServer server_b(processor, serverTransport_b,
transportFactory_b,
protocolFactory_b, threadManager_b);
server_b.serve();
return 0;
}
Happy to provide more details if needed.
Thanks,
Parvesh Garg
Parvesh Garg
2017-07-14 17:56:42 UTC
Permalink
Hi Randy,

Thanks a lot for your response. Actually, this is exactly the behavior i'm
looking for, not concurrency. My client takes time before it can construct
an event, meanwhile the server was idle. Sequence of events is important,
so no concurrency.

Thanks again
Post by Randy Abernethy
Hey Parvesh,
The C++ Threaded and ThreadPool severs assign a single thread to each
connection. So if you send 10 requests (one way) on a single connection a
single server thread will handle them in order (serially). Even the
nonblocking C++ server handles requests serially per connection (though it
can process tasks from many different connections at once in the task
pool). While not always the most efficient model, this serial per
connection approach guarantees that multiple requests on a single
connection behave like serial function calls (which is the essence of the
RPC model).
Sounds like what you are trying to do (and what one-way half way enables)
is to send async messages to a server that it can process concurrently. If
you want concurrency on a single connections requests the easiest path
(IMHO) is to queue the work to a background thread pool for processing.
Hope this helps,
Randy
Post by Parvesh Garg
Hi,
I have a basic question about how the oneway method called from client
work
Post by Parvesh Garg
with TThreadPoolServer. We have a server written in C++ that uses thread
pool server with 4 threads. The client in python connects only once and
keep pushing data to server using a oneway method. Our doubt is will the
server queue the events and process them in a single thread or spawn
multiple threads to take care of each event?
Client is single threaded.
Thrift version is 0.10.0
Here is a glimpse of code showing how the server is configured.
int main(int /*argc*/, char ** /*argv*/) {
boost::shared_ptr<AppServerHandler> handler(new AppServerHandler());
boost::shared_ptr<TProcessor> processor(new
AppServerProcessor(handler));
Post by Parvesh Garg
int port_b = 9090;
boost::shared_ptr<TServerTransport> serverTransport_b(new
TServerSocket(port_b));
boost::shared_ptr<TTransportFactory> transportFactory_b(new
TBufferedTransportFactory());
boost::shared_ptr<TProtocolFactory> protocolFactory_b(new
TBinaryProtocolFactory());
boost::shared_ptr<ThreadManager> threadManager_b =
ThreadManager::newSimpleThreadManager(4);
boost::shared_ptr<PosixThreadFactory> threadFactory_b(new
PosixThreadFactory());
threadManager_b->threadFactory(threadFactory_b);
threadManager_b->start();
TThreadPoolServer server_b(processor, serverTransport_b,
transportFactory_b,
protocolFactory_b, threadManager_b);
server_b.serve();
return 0;
}
Happy to provide more details if needed.
Thanks,
Parvesh Garg
Loading...