Frequently Asked Questions
If the operation has a void return type and does not have out-parameters or an exception specification, you may be tempted to simply call the operation via a oneway proxy, thinking that this makes it impossible for the client to block when it invokes the operation. Unfortunately, this is incorrect: oneway operations can indeed block.
There are two scenarios that can cause a oneway invocation to block the caller:
Connection EstablishmentIf no connection to the target server for an invocation is currently established, the Ice runtime will transparently open a connection (whether the call is oneway or twoway). Connection establishment forces the Ice runtime to wait for a connection validation message from the server, as required by the Ice protocol. If the server is slow to respond, has run out of threads to process its incoming connection request, or misbehaves in other ways, an invocation (including a oneway invocation) can block. If you set a timeout, the call will throw a ConnectionTimeoutException once the timer expires; without a timeout, the call can block indefinitely. Regardless, connection establishment is identical for oneway and twoway operations and can block the client.
Note that you can mitigate the problem somewhat by forcing a connection to be established initially, for example, by disabling ACM and sending an ice_ping() before you send a oneway invocation. However, because connections may be closed due to networking problems, this only makes it less likely for a oneway call to block, but does not prevent it, because, during a retry of a failed invocation, the Ice runtime may attempt to re-establish a connection and block at that point.
TCP/IP Buffer LimitationsThe client's local TCP/IP stack has a limited amount of buffer space to accept data. If a oneway request is too large to fit into the remaining TCP/IP buffer space, the kernel suspends the caller in its write system call on the socket until enough buffer space becomes available. The remaining buffer space can be consumed by previously buffered requests or even by a single request, if it is large enough. Either way, a oneway invocation can block until the TCP/IP stack has removed enough data from its buffers for the currently executing request to be buffered, at which point the oneway invocation returns the thread of control to the application code.