From 976fab5a291d4f22818751a813e48cd39471beca Mon Sep 17 00:00:00 2001 From: Jacob Quinn Date: Thu, 25 Aug 2022 07:15:38 -0600 Subject: [PATCH] When monitoring idle connections, only call eof on tcp socket (#912) * When monitoring idle connections, only call eof on tcp socket In a heavy cloud storage workflow, I encountered the following error: ``` AssertionError: ctx.bytesavailable > 0 || !(ctx.isreadable) ``` with traces back to calling `eof(::SSLContext)` from `monitor_idle_connection`. As the workflow was highly concurrent, I believe the error was just a data race between an old async `monitor_idle_connection` task calling `eof` -> `wait_for_decrypted_data`, but when returning from `wait_for_decrypted_data` due to a new connection being reused in HTTP.jl, the `handshake` was redone, which resulted in the `AssertionError` shown above. The proposal here is that when monitoring idle connections, we only call `eof` on the underlying TCPSocket, since we're really only concerned with knowing whether the core socket gets additional data, encrypted or not, when we don't expect it. * simplify --- src/ConnectionPool.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ConnectionPool.jl b/src/ConnectionPool.jl index 5ca877cad..f47a696a3 100644 --- a/src/ConnectionPool.jl +++ b/src/ConnectionPool.jl @@ -261,8 +261,8 @@ TODO: or if response data arrives when no request was sent (isreadable == false) """ function monitor_idle_connection(c::Connection) try - if eof(c.io) ;@debugv 3 "💀 Closed: $c" - close(c.io) + if eof(tcpsocket(c.io)) ;@debugv 3 "💀 Closed: $c" + isopen(c.io) && close(c.io) end catch ex @try Base.IOError close(c.io)