-- | Definition of 'RequestHandler' -- -- Defined in a separate module to avoid cyclic module dependencies. -- -- Intended for unqualified import. module Network.GRPC.Server.RequestHandler.API ( RequestHandler , requestHandlerToServer ) where import Control.Exception import Network.HTTP2.Server qualified as HTTP2 {------------------------------------------------------------------------------- Definition -------------------------------------------------------------------------------} -- | HTTP2 request handler type RequestHandler a = (forall x. IO x -> IO x) -> HTTP2.Request -> (HTTP2.Response -> IO ()) -> IO a -- | Construct @http2@ handler requestHandlerToServer :: RequestHandler () -- ^ Request handler -- -- We can assume in 'requestHandlerToServer' that the handler will not -- throw any exceptions (doing so will cause @http2@ to reset the stream, -- which is not always the right thing to do; see detailed comments in -- 'runHandler'). It is the responsibility of 'serverTopLevel' (prior to -- calling 'requestHandlerToServer') to catch any remaining exceptions. -> HTTP2.Server requestHandlerToServer :: RequestHandler () -> Server requestHandlerToServer RequestHandler () handler Request req Aux _aux Response -> [PushPromise] -> IO () respond = -- We start by masking asynchronous exceptions. It is possible that -- http2 kills us /before/ this call to @mask@, but if it does, no harm -- is done: nothing has happened yet, so nothing is interrupted. ((forall a. IO a -> IO a) -> IO ()) -> IO () forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b mask (((forall a. IO a -> IO a) -> IO ()) -> IO ()) -> ((forall a. IO a -> IO a) -> IO ()) -> IO () forall a b. (a -> b) -> a -> b $ \forall a. IO a -> IO a unmask -> RequestHandler () handler IO x -> IO x forall a. IO a -> IO a unmask Request req (\Response resp -> Response -> [PushPromise] -> IO () respond Response resp [])