connection-pool-0.1.3: src/Data/ConnectionPool/Internal/Streaming.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NoImplicitPrelude #-}
-- |
-- Module: $HEADER$
-- Description: Helper functions that aren't provided by streaming-commons.
-- Copyright: (c) 2014-2015, Peter Trško
-- License: BSD3
--
-- Maintainer: peter.trsko@gmail.com
-- Stability: unstable (internal module)
-- Portability: CPP, FlexibleContexts, NoImplicitPrelude
--
-- Module defines helper functions that would be ideally provided by
-- <http://hackage.haskell.org/package/streaming-commons streaming-commons>
-- package and some wrappers with specialised type signatures.
--
-- Internal packages are here to provide access to internal definitions for
-- library writers, but they should not be used in application code.
--
-- Preferably use qualified import, e.g.:
--
-- > import qualified Data.ConnectionPool.Internal.Streaming as Internal
--
-- This module doesn't neither depend on
-- <http://hackage.haskell.org/package/resource-pool resource-pool> package nor
-- any other module of this package, with notable exception of
-- "Data.ConnectionPool.Internal.HandlerParams", and it shoud stay that way.
-- This module uses CPP to get OS specific things right. Most importantly
-- Windows doesn't support UNIX Sockets.
--
-- Please, bear above in mind when doing modifications.
module Data.ConnectionPool.Internal.Streaming
(
-- * TCP
acquireTcpClientConnection
, runTcpApp
, runTcpAppImpl
, fromClientSettings
#ifndef WINDOWS
-- Windows doesn't support UNIX Sockets.
-- * Unix Socket
, runUnixApp
, runUnixAppImpl
, fromClientSettingsUnix
#endif
-- !WINDOWS
)
where
import Data.Int (Int)
import Data.Maybe (Maybe(Just))
import System.IO (IO)
import Control.Monad.Trans.Control (MonadBaseControl)
import Network.Socket (Socket, SockAddr, sClose)
import Network.Socket.ByteString (sendAll)
import Data.Default.Class (Default(def))
import Data.Streaming.Network
( getSocketFamilyTCP
, safeRecv
#if MIN_VERSION_streaming_commons(0,1,13)
-- Until streaming-commons 0.1.13, read buffer size was fixed.
, getReadBufferSize
#endif
)
import Data.Streaming.Network.Internal
( AppData(AppData)
, ClientSettings(clientPort, clientHost, clientAddrFamily)
#ifndef WINDOWS
-- Windows doesn't support UNIX Sockets.
, AppDataUnix(AppDataUnix)
#if MIN_VERSION_streaming_commons(0,1,13)
-- Until streaming-commons 0.1.13, read buffer size was fixed. For some
-- mistifying reason there is no
--
-- instance HasReadBufferSize ClientSettingsUnix".
, ClientSettingsUnix(clientReadBufferSizeUnix)
#endif
-- streaming-commons >= 0.1.13
#endif
-- !WINDOWS
)
import qualified Data.Streaming.Network.Internal as AppData
( AppData
( appLocalAddr'
, appRead'
, appSockAddr'
, appWrite'
#if MIN_VERSION_streaming_commons(0,1,6)
, appCloseConnection'
#endif
#if MIN_VERSION_streaming_commons(0,1,12)
, appRawSocket'
#endif
))
import Data.ConnectionPool.Internal.HandlerParams
( HandlerParams(_readBufferSize)
)
#ifndef WINDOWS
-- Windows doesn't support UNIX Sockets.
import qualified Data.Streaming.Network.Internal as AppDataUnix
(AppDataUnix(appReadUnix, appWriteUnix))
#endif
-- !WINDOWS
-- | Wrapper for 'runTcpAppImpl' with a type signature that is more natural
-- for implementing a TCP specific
-- 'Data.ConnectionPool.Internal.ConnectionPool.withConnection'.
runTcpApp
:: MonadBaseControl IO m
=> Maybe SockAddr
-> (AppData -> m r)
-> HandlerParams
-> Socket
-> SockAddr
-> m r
runTcpApp localAddr app params sock addr =
runTcpAppImpl localAddr sock addr bufSize app
where
bufSize = _readBufferSize params
-- | Simplified 'Data.Streaming.Network.runTCPClient' and
-- 'Data.Streaming.Network.runTCPServer' that provides only construction of
-- 'AppData' and passing it to a callback function.
runTcpAppImpl
:: MonadBaseControl IO m
=> Maybe SockAddr
-> Socket
-> SockAddr
-> Int
-> (AppData -> m r)
-> m r
runTcpAppImpl localAddr sock addr bufSize app = app AppData
{ AppData.appRead' = safeRecv sock bufSize -- :: !(IO ByteString)
, AppData.appWrite' = sendAll sock -- :: !(ByteString -> IO ())
, AppData.appSockAddr' = addr -- :: !SockAddr
, AppData.appLocalAddr' = localAddr -- :: !(Maybe SockAddr)
#if MIN_VERSION_streaming_commons(0,1,6)
, AppData.appCloseConnection' = sClose sock -- :: !(IO ())
#endif
#if MIN_VERSION_streaming_commons(0,1,12)
, AppData.appRawSocket' = Just sock -- :: Maybe Socket
#endif
}
-- | Wrapper for 'getSocketFamilyTCP' that takes 'ClientSettings' instead of
-- individual parameters.
acquireTcpClientConnection :: ClientSettings -> IO (Socket, SockAddr)
acquireTcpClientConnection settings = getSocketFamilyTCP host port addrFamily
where
port = clientPort settings
host = clientHost settings
addrFamily = clientAddrFamily settings
fromClientSettings :: ClientSettings -> HandlerParams
fromClientSettings _tcpParams = def
#if MIN_VERSION_streaming_commons(0,1,13)
-- Until streaming-commons 0.1.13, read buffer size was fixed.
{ _readBufferSize = getReadBufferSize _tcpParams
}
#endif
#ifndef WINDOWS
-- Windows doesn't support UNIX Sockets.
-- | Wrapper for 'runUnixAppImpl' with a type signature that is more natural
-- for implementing a UNIX Socket specific
-- 'Data.ConnectionPool.Internal.ConnectionPool.withConnection'.
runUnixApp
:: MonadBaseControl IO m
=> (AppDataUnix -> m r)
-> HandlerParams
-> Socket
-> ()
-> m r
runUnixApp app params sock () = runUnixAppImpl sock bufSize app
where
bufSize = _readBufferSize params
-- | Simplified 'Data.Streaming.Network.runUnixClient' and
-- 'Data.Streaming.Network.runUnixServer' that provides only construction of
-- 'AppDataUnix' and passing it to a callback function.
runUnixAppImpl
:: MonadBaseControl IO m
=> Socket
-> Int
-> (AppDataUnix -> m r)
-> m r
runUnixAppImpl sock bufSize app = app AppDataUnix
{ AppDataUnix.appReadUnix = safeRecv sock bufSize
, AppDataUnix.appWriteUnix = sendAll sock
}
fromClientSettingsUnix :: ClientSettingsUnix -> HandlerParams
fromClientSettingsUnix _unixParams = def
#if MIN_VERSION_streaming_commons(0,1,13)
-- Until streaming-commons 0.1.13, read buffer size was fixed.
{ _readBufferSize = clientReadBufferSizeUnix _unixParams
}
#endif
-- streaming-commons >= 0.1.13
#endif
-- !WINDOWS