supernova-0.0.3: src/Pulsar/Internal/TCPClient.hs
{-# LANGUAGE LambdaCase, OverloadedStrings, RankNTypes #-}
{- A simple TCP client, used to communicate with the Pulsar server -}
module Pulsar.Internal.TCPClient
( acquireSocket
)
where
import Control.Monad.Catch ( bracket
, bracketOnError
)
import Control.Monad.IO.Class ( MonadIO
, liftIO
)
import Control.Monad.Managed ( MonadManaged
, managed
, using
)
import qualified Network.Socket as NS
acquireSocket
:: (MonadIO m, MonadManaged m) => NS.HostName -> NS.ServiceName -> m NS.Socket
acquireSocket host port = do
addr <- liftIO resolve
using $ managed (bracket (acquire addr) release)
where
acquire = (putStrLn "[ Establishing connection with Pulsar ]" >>) . open
release = (putStrLn "[ Closing Pulsar connection ]" >>) . NS.close
resolve = do
let hints = NS.defaultHints { NS.addrSocketType = NS.Stream }
NS.getAddrInfo (Just hints) (Just host) (Just port) >>= \case
[addr] -> pure addr
_ -> ioError $ userError "Could not resolve socket address"
open addr = bracketOnError (NS.openSocket addr) NS.close $ \sock -> do
NS.connect sock $ NS.addrAddress addr
return sock