Description
When using the NIOAsyncChannel.executeThenClose
it is easy to lose writes. The following code is prone to this
try await channel.executeThenClose { inbound, outbound in
try await outbound.write(...)
}
The problem here is that while write
is async
it doesn't wait for the write to actually hit the socket. We did this to avoid allocating a promise for every single write. However, this also means that the write might be buffered in the pipeline or the channel itself. Once we return from the closure of executeThenClose
we are calling channel.close()
which leads to a forceful closure of the channel. This means that any potentially buffered write might get dropped.
Even when using outbound half closure this can happen since outbound.finish
is not async and not waiting for the half closure to be written out.
A few options that I thought about so far:
- Allocate a promise for every write. This would trade correctness for performance.
- Introduce a new soft close mode in the channel pipeline that allows all writes to get flushed and then close