[Haskell-cafe] Amazonka, conduit and sockets not closing
Bryan Richter
b at chreekat.net
Sat Nov 28 16:41:57 UTC 2020
I thought CLOSE_WAIT *is* one of the "closed" states. TCP sockets
stick around for a few minutes after use, right? You may simply be
generating sockets faster than one operating system can handle. Find
some way to reuse existing sockets, perhaps?
On Thu, Nov 26, 2020 at 3:13 PM Magnus Therning <magnus at therning.org> wrote:
>
> I've run into a problem with running out of filedescriptors. The
> following snippet is a trimmed down version of what I'm doing:
>
> #+begin_src haskell
> main :: IO ()
> main = do
> awsEnv <- newEnv Discover
> runAWSCond awsEnv $
> sqsSource queueUrl
> .| C.mapC snd
> .| sqsDeleteSink queueUrl
> where
> runAWSCond awsEnv = runResourceT . runAWS awsEnv . within Frankfurt . C.runConduit
>
> sqsSource :: MonadAWS m => T.Text -> C.ConduitT () (T.Text, T.Text) m ()
> sqsSource queueUrl = do
> (_, msgs) <- C.lift $ recvSQS queueUrl
> C.yieldMany msgs
> sqsSource queueUrl
>
> sqsDeleteSink :: MonadAWS m => T.Text -> C.ConduitT T.Text o m ()
> sqsDeleteSink queueUrl = do
> C.await >>= \case
> Nothing -> pure ()
> Just receiptHandle -> do
> void $ C.lift $ delSQS queueUrl receiptHandle
> sqsDeleteSink queueUrl
>
> recvSQS queueUrl = do
> let rm = receiveMessage queueUrl & rmMaxNumberOfMessages ?~ 10
> rmrs <- send rm
> let status = rmrs ^. rmrsResponseStatus
> msgs = rmrs ^. rmrsMessages & traversed %~ extract
> pure (status, catMaybes msgs)
> where
> extract msg = do
> body <- msg ^. mBody
> rh <- msg ^. mReceiptHandle
> pure (body, rh)
>
> delSQS queueUrl receiptHandle = do
> let dm = deleteMessage queueUrl receiptHandle
> send dm
> #+end_src
>
> This works fine for a while, but given a queue with enough messages it will fail
> with something like
>
> #+begin_example
> TransportError (HttpExceptionRequest Request {
> host = "sqs.eu-central-1.amazonaws.com"
> port = 443
> secure = True
> requestHeaders = [("Host","sqs.eu-central-1.amazonaws.com"),("X-Amz-Date","20201126T101659Z"),("X-Amz-Content-SHA256","2e4bdf20a857a1416f218b1218670cf019ff53268d0adb34fe06402a62f3271d"),("Content-Type","application/x-www-form-urlencoded; charset=utf-8"),("Authorization","<REDACTED>")]
> path = "/"
> queryString = ""
> method = "POST"
> proxy = Nothing
> rawBody = False
> redirectCount = 0
> responseTimeout = ResponseTimeoutMicro 70000000
> requestVersion = HTTP/1.1
> }
> (ConnectionFailure Network.Socket.getAddrInfo (called with preferred socket type/protocol: AddrInfo {addrFlags = [AI_ADDRCONFIG], addrFamily = AF_UNSPEC, addrSocketType = Stream, addrProtocol = 0, addrAddress = <assumed to be undefined>, addrCanonName = <assumed to be undefined>}, host name: Just "sqs.eu-central-1.amazonaws.com", service name: Just "443"): does not exist (System error)))
> #+end_example
>
> After some detours I found out that it's actually not a network issue, but
> rather that the process runs out of filedescriptors. Using =lsof= I can see that
> it doesn't seem to close /any/ sockets at all, instead they get stuck in a
> =CLOSE_WAIT= state:
>
> #+begin_example
> COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
> wd-stats 88674 magnus 23u IPv4 815196 0t0 TCP ip-192-168-0-9.eu-central-1.compute.internal:60624->52.119.188.213:https (CLOSE_WAIT)
> wd-stats 88674 magnus 24u IPv4 811362 0t0 TCP ip-192-168-0-9.eu-central-1.compute.internal:43482->52.119.189.184:https (CLOSE_WAIT)
> wd-stats 88674 magnus 25u IPv4 811386 0t0 TCP ip-192-168-0-9.eu-central-1.compute.internal:60628->52.119.188.213:https (CLOSE_WAIT)
> wd-stats 88674 magnus 26u IPv4 813527 0t0 TCP ip-192-168-0-9.eu-central-1.compute.internal:43486->52.119.189.184:https (CLOSE_WAIT)
> ...
> #+end_example
>
> Am I using Amazonka and/or Conduit in a way that results in this? How do I should I use them?
>
> Or, is it an issue somewhere "below" my code? What can I do address that?
>
> Thanks for any insights or help
> /M
>
> --
> Magnus Therning OpenPGP: 0x927912051716CE39
> email: magnus at therning.org
> twitter: magthe http://magnus.therning.org/
>
> Action is the foundational key to all success.
> — Pablo Picasso
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
More information about the Haskell-Cafe
mailing list