6.4.10. Fixes Related to Request-Reply and RPC
6.4.10.1. [Critical] Exceptions sending result of remote operation may have crashed server application
In an RPC server-side application, the user implements the functional interface. The Server uses a thread pool to call those functions with the input sent from the client (Request) and obtain the result. The result is then sent to the client (Reply). The Reply is automatically written using a DDS DataWriter. If the write() operation failed, the resulting exception would crash the current thread in the thread pool and possibly crash the entire server-side application (a typical write() exception is a Timeout). Since the Reply is sent by the server from a separate thread, the user application has no way of catching the exception or sending the Reply again.
This problem has been resolved. If an exception occurs, it is caught and logged. The Reply is never sent. User applications have two ways to react to this event:
The server application can install a rti::config::Logger::output_handler to monitor errors.
The client application will see a timeout in the function call. The application can then react accordingly (e.g., calling the function again later).
[RTI Issue ID REQREPLY-111]
6.4.10.2. [Critical] RPC: deadlock when Server::close() was called before Server::run()
In the unlikely scenario that a Server was created and then closed before running (the method Server::close() was called before Sever::run()), run() would never return unless a timeout was specified. This problem has been resolved.
[RTI Issue ID REQREPLY-113]
6.4.10.3. [Critical] Possible unbounded memory growth when creating many Requesters
This issue was fixed in release 7.0.0, but not documented at that time.
When a Requester is created, a ContentFilteredTopic is internally created on the Requester’s DomainParticipant. This ContentFilteredTopic is exclusively created for each Requester and was never deleted until the DomainParticipant was deleted. This may have caused applications that continuously create and delete Requesters on the same DomainParticipant to see unbounded memory growth.
This problem has been resolved in all language APIs. The Requester destructor or deletion function now deletes its ContentFilteredTopic.
[RTI Issue ID REQREPLY-35]
6.4.10.4. [Critical] Memory leak in Java Request-Reply API
This issue was fixed in release 7.0.0, but not documented at that time.
The Java Request-Reply API leaked a small amount of native heap memory every time a Requester was created. The leak was caused by a few internal WaitSet objects, which did not have a finalizer and were not explicitly deleted either.
[RTI Issue ID REQREPLY-94]
6.4.10.5. [Critical] Possible data race using Sample and WriteSample classes (Traditional C++ API only)
This issue was fixed in release 7.0.0, but not documented at that time.
The Sample and WriteSample classes are wrapper classes in the Traditional C++ Request-Reply API that used to initialize the underlying user data lazily: the data was initialized the first time it was accessed with the data() member function.
This approach made the access to the data unsafe. A data race could occur when two or more threads competed to access the same sample object for the first time. This problem has been resolved. The lazy approach has been reversed, and the data is now initialized in the constructor.
[RTI Issue ID REQREPLY-95]
6.4.10.6. [Major] RPC interface evolution did not work
Remote Procedure Call (RPC) interfaces were designed to be extensible. A service and a client can communicate even when they have a different number of interfaces. For example:
A base service definition in IDL could be as follows:
@service
interface RobotControl {
Coordinates walk_to(Coordinates destination, float speed);
float get_speed();
};
If you add new operations to the service interface, such as the following:
@service
interface RobotControl {
Coordinates walk_to(Coordinates destination, float speed);
float get_speed();
float get_position();
};
Or remove operations from the service interface, such as the following:
@service
interface RobotControl {
Coordinates walk_to(Coordinates destination, float speed);
};
They should remain interoperable.
However, in the previous release, the service and the client wouldn’t communicate in any case.
This problem has been resolved. A client can now invoke an operation in a service with more or fewer operations. If the operation exists in the service, it will receive a valid response. If the operation doesn’t exist in the service, the service will respond accordingly and the client will throw the standard exception dds::rpc::RemoteUnknownOperationError.
[RTI Issue ID REQREPLY-105]