-
Type: Improvement
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
Because the net.Conn.Read and net.Conn.Write functions don't take a context, the driver doesn't respect context cancellation once an operation has been dispatched to the server. This creates confusing semantics for users who expect blocking work to stop on context cancellation. Some ideas/thoughts I've had about this:
- We can spin up a separate goroutine in ReadWireMessage/WriteWireMessage to listen for ctx.Done and close the connection or set it's read/write deadline to a previous time. We'll need to ensure we return context.Cancelled rather than the net.Error from the read/write call so the server pool isn't unnecessarily cleared.
- The first suggestion can cause connection churn. If users are using context cancellation to signal some sort of shutdown, this is probably fine. If it's being used to implement things like application-level hedging, unnecessarily invalidating connections could cause issues. The only idea I have for doing is cleanly is to send an out of band killOp command, but this requires checking out another connection from the pool (or making a dedicated one?) and also first running currOp to get the operation ID. This might not be acceptable because we'd be doing two blocking round trips after the context has been cancelled.
- Killing the session associated with the op works too and is only one roundtrip, but I've been told that it's a relatively expensive operation because sessions have a lot of server-side state (e.g. retryable writes, transactions, etc).