Skip to content

Using receive(long timeout) to await the reply for RPC call limits throughput to 10/second #65

@wheezil

Description

@wheezil

To reproduce:
Unpack and build the attached archive.
On one command-line start the server:
java -cp example-1.0-shaded.jar JMSPassiveRpcServerTest
On a second command-line run the client:
java -cp example-1.0-shaded.jar JMSRpcClientTest
Expected result : throughput is at least 100s/second, especially if the ITER constant is made larger than 100.
Actual result : throughput is less than 10/second.

Note that a native RabbitMQ RPC client/server test is also included in this archive (classes RpcClientTest and RpcServerTest), which achieves good performance.

My analysis:
The MessageConsumer.receive(long timeout) method is implemented using DelayedReceiver. When DelayedReceiver.get() finds that no message is available, it sleeps for 100ms before trying again. Since it is almost always the case that the server has not replied before receive() is called by an RPC client, every call tends to incur this penalty.

Suggested solution:
Implement MessageConsumer.receive() using a background receiver to accept messages and a thread-safe queue to exchange messages between background and foreground, similar to the implementation of the RabbitMQ RPCClient class. Note that this may induce some complexity in the implementation, or make it impossible for a client to both call receive() AND use a MessageListener on the same Connection (however, I think this is already disallowed -- you cannot both have a MessageListener and call receive())..
rabbitmq-rpc-example.zip

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions