bloomberg / bloomberg/ntf-core
Reads with deadline
- Dominant language
- C++
- Stars
- 99
- Forks
- 33
- PR merge metrics
- No merged PRs in 30d
Description
I have a client written with NTF. The client connects to an existing server. Immediately after connecting, it sends a 64-byte message to the server, and the server immediately responds with a 64-byte reply. Client and server run on the same machine and talk over the backplane. (The server is pre-existing code, not written using NTF.)
The client socket is created like so:
```
ntca::StreamSocketOptions sock_opts;
sock_opts.setLingerFlag(false);
sock_opts.setLingerTimeout(0);
socket_ = interface_->createStreamSocket(sock_opts);
```
After establishing the connection and sending its 64-byte message, the client reads the server's reply like so:
```
ntca::ReceiveOptions r_opts;
r_opts.setMinSize(64);
r_opts.setMaxSize(64);
auto callback = socket_->createReceiveCallback([this](auto receiver, auto blob, auto event) {
received_identity(receiver, blob, event);
});
auto error = socket_->receive(r_opts, callback);
if (error) {
CS_LOG(FATAL) << "Cannot schedule receive: " << error.text();
abort();
}
```
This works just fine. The callback pops without error, and the client gets the expected response from the server.
Now I want to add a timeout of 500 ms to the client. If the reply from the server does not arrive in that time, the client can take some error action. So, I change the receive like so:
```
ntca::ReceiveOptions r_opts;
r_opts.setMinSize(64);
r_opts.setMaxSize(64);
const int64_t millisecs = 500;
BloombergLP::bsls::TimeInterval timeout;
timeout.setTotalMilliseconds(millisecs);
r_opts.setDeadline(timeout);
auto callback = socket_->createReceiveCallback([this, millisecs](auto receiver, auto blob, auto event) {
received_identity(receiver, blob, event, millisecs);
});
auto error = socket_->receive(r_opts, callback);
if (error) {
CS_LOG(FATAL) << "Cannot schedule receive: " << error.text();
abort();
}
```
The only change here is to add the timeout to the receive options. Now things do not work. The server gets the message as usual and responds to it, but the callback in the client pops immediately with e_WOULD_BLOCK. If I run the client many times, after about 30 or 50 attempts, it successfully get the response from the server. The whole thing behaves like the timeout is zero or near zero. Every now and then, the response from the server arrives quickly enough, but most of the time, the timeout prevents things from working.
I played around with the timeout value:
```
const int64_t millisecs = 500000000000; // 5 * 10^11
```
This still fails. But once I add another zero, things work on the first try every time:
```
const int64_t millisecs = 5000000000000; // 5 * 10^12
```
What gives?
Contributor guide
Assessment
This issue has not been assessed yet.