cpp-channel/Thrift/Channel/Lib/HeaderChannel.hs (99 lines of code) (raw):
-- Copyright (c) Facebook, Inc. and its affiliates.
{-# LANGUAGE StandaloneDeriving #-}
module Thrift.Channel.Lib.HeaderChannel
( HeaderWrappedChannel
, HeaderConfig(..)
, getRequestChannelProtocolId
, withHeaderChannelForTransport
, withHeaderChannelIOForTransport
) where
import Control.Exception
import Data.ByteString (ByteString)
import qualified Data.ByteString.Unsafe as BS
import Data.Proxy
import Foreign.C
import Foreign.Ptr
import Thrift.Channel.Lib.CppChannel
import Thrift.Monad
import Thrift.Protocol
import Thrift.Protocol.Id
import Util.EventBase
data HeaderClient
type HeaderWrappedChannel = WrappedChannel HeaderClient
data HeaderConfig a = HeaderConfig
{ headerHost :: ByteString
, headerPort :: Int
, headerProtocolId :: ProtocolId
, headerConnTimeout :: Int
, headerSendTimeout :: Int
, headerRecvTimeout :: Int
}
deriving instance Show (HeaderConfig a)
withHeaderChannelForTransport
:: EventBaseDataplane
-> HeaderConfig t
-> FunPtr (CppSocketAddress -> EventBase -> CSize
-> IO (Ptr CppAsyncTransport))
-> (forall p . Protocol p => ThriftM p HeaderWrappedChannel t a)
-> IO a
withHeaderChannelForTransport io HeaderConfig{..} transportMaker fn = do
eb <- getEventBase io
BS.unsafeUseAsCStringLen headerHost $ \(host_str, host_len) -> bracket
(newHeaderChannel host_str (fromIntegral host_len)
(fromIntegral headerPort)
transportMaker
headerProtocolId
(fromIntegral headerConnTimeout)
(fromIntegral headerSendTimeout)
(fromIntegral headerRecvTimeout)
eb
)
deleteHeaderChannel $ \ch -> do
protId <- getRequestChannelProtocolId ch
withProxy protId $ runAction ch fn
where
runAction
:: Protocol p
=> Ptr CppRequestChannelPtr
-> ThriftM p HeaderWrappedChannel t a
-> Proxy p
-> IO a
runAction c a _ = withCppChannel c a
withHeaderChannelIOForTransport
:: EventBaseDataplane
-> HeaderConfig t
-> FunPtr (CppSocketAddress -> EventBase -> CSize
-> IO (Ptr CppAsyncTransport))
-> (forall p . Protocol p => HeaderWrappedChannel t -> Proxy p -> IO a)
-> IO a
withHeaderChannelIOForTransport io HeaderConfig{..} transportMaker fn = do
eb <- getEventBase io
BS.unsafeUseAsCStringLen headerHost $ \(host_str, host_len) -> bracket
(newHeaderChannel host_str (fromIntegral host_len)
(fromIntegral headerPort)
transportMaker
headerProtocolId
(fromIntegral headerConnTimeout)
(fromIntegral headerSendTimeout)
(fromIntegral headerRecvTimeout)
eb
)
deleteHeaderChannel $ \ch -> do
protId <- getRequestChannelProtocolId ch
withCppChannelIO ch $ \ wr -> do
withProxy protId $ fn wr
foreign import ccall safe "newHeaderChannel"
newHeaderChannel :: CString -> CSize
-> CSize
-> FunPtr (CppSocketAddress -> EventBase -> CSize
-> IO (Ptr CppAsyncTransport))
-> CUShort
-> CSize
-> CSize
-> CSize
-> EventBase
-> IO (Ptr CppRequestChannelPtr)
foreign import ccall safe "deleteHeaderChannel"
deleteHeaderChannel :: Ptr CppRequestChannelPtr -> IO ()
foreign import ccall unsafe "getRequestChannelProtocolId"
getRequestChannelProtocolId :: Ptr CppRequestChannelPtr -> IO CUShort