|
closeConnection :: Connection -> IO () |
|
closeConnection c = do |
|
CE.catch ( |
|
withMVar (connWriteLock c) $ \_ -> writeFrame (connHandle c) $ Frame 0 $ MethodPayload $ Connection_close |
|
--TODO: set these values |
|
0 -- reply_code |
|
(ShortString "") -- reply_text |
|
0 -- class_id |
|
0 -- method_id |
|
) |
|
(\ (_ :: CE.IOException) -> |
|
--do nothing if connection is already closed |
|
return () |
|
) |
closeConnection swallows any IO exceptions it might encounter upon sending the close connection message to the server, and then waits on the server indefinitely, expecting the server to send back a connection_closed_ok message.
One problem I see is that if an IO exception is encountered when sending the server the close connection message, there is no reason to expect that the server has properly received the message, and therefore no reason to expect that the server will respond with a connection_closed_ok message.
In such a case, the MVar contents will never become full, and the call to readMVar will block forever. From the readMVar docs:
Atomically read the contents of an MVar. If the MVar is currently empty, readMVar will wait until it is full.
https://www.stackage.org/haddock/lts-18.22/base-4.14.3.0/Control-Concurrent-MVar.html#v:readMVar
I would propose that closeConnection at a minimum be altered such that readMVar is not called if an IO exception is encountered.
amqp/Network/AMQP/Internal.hs
Lines 418 to 431 in 3ddd972
closeConnectionswallows any IO exceptions it might encounter upon sending the close connection message to the server, and then waits on the server indefinitely, expecting the server to send back a connection_closed_ok message.One problem I see is that if an IO exception is encountered when sending the server the close connection message, there is no reason to expect that the server has properly received the message, and therefore no reason to expect that the server will respond with a connection_closed_ok message.
In such a case, the
MVarcontents will never become full, and the call toreadMVarwill block forever. From thereadMVardocs:https://www.stackage.org/haddock/lts-18.22/base-4.14.3.0/Control-Concurrent-MVar.html#v:readMVar
I would propose that
closeConnectionat a minimum be altered such thatreadMVaris not called if an IO exception is encountered.