Created
February 5, 2020 15:50
-
-
Save chrisdone/8b3622539bef18c24ed7fcb595b5d7db to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE ScopedTypeVariables #-} | |
-- | A ResourceT-based way to use connections with conduit. | |
module Data.Conduit.Network.Resource where | |
import qualified Network.Socket as NS | |
import Control.Exception | |
import Control.Monad.IO.Class | |
import Control.Monad.Trans.Resource | |
import Data.Streaming.Network | |
import Data.Streaming.Network.Internal | |
import Network.Socket.ByteString (sendAll) | |
-- | Allocate a TCP client that will be close automatically by the | |
-- resource monad. | |
allocateTCPClient :: | |
(MonadIO m, MonadResource m) | |
=> ClientSettings | |
-> m (Either IOException (ReleaseKey, AppData)) | |
allocateTCPClient (ClientSettings port host addrFamily readBufferSize) = do | |
result <- allocate (try allocator) freer | |
case result of | |
(releaseKey, Right appData) -> pure (Right (releaseKey, appData)) | |
(_, Left ioexception) -> pure (Left ioexception) | |
where | |
allocator = do | |
(s, address) <- liftIO (getSocketFamilyTCP host port addrFamily) | |
pure | |
AppData | |
{ appRead' = safeRecv s readBufferSize | |
, appWrite' = sendAll s | |
, appSockAddr' = address | |
, appLocalAddr' = Nothing | |
, appCloseConnection' = NS.close s | |
, appRawSocket' = Just s | |
} | |
freer :: Either IOException AppData -> IO () | |
freer = either (const (pure ())) appCloseConnection' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment