mirror of
https://github.com/unclechu/gRPC-haskell.git
synced 2024-07-01 08:58:35 +02:00
106 lines
4.2 KiB
Haskell
106 lines
4.2 KiB
Haskell
|
{-# LANGUAGE DataKinds #-}
|
||
|
{-# LANGUAGE GADTs #-}
|
||
|
{-# LANGUAGE OverloadedStrings #-}
|
||
|
{-# LANGUAGE RankNTypes #-}
|
||
|
{-# LANGUAGE RecordWildCards #-}
|
||
|
|
||
|
module Network.GRPC.HighLevel.Server.Unregistered where
|
||
|
|
||
|
import Control.Applicative ((<|>))
|
||
|
import Control.Concurrent.Async
|
||
|
import Control.Monad
|
||
|
import Data.ByteString (ByteString)
|
||
|
import Data.Protobuf.Wire.Class
|
||
|
import Data.Foldable (find)
|
||
|
import Network.GRPC.HighLevel.Server
|
||
|
import Network.GRPC.LowLevel
|
||
|
import Network.GRPC.LowLevel.GRPC
|
||
|
import Network.GRPC.LowLevel.Call
|
||
|
import qualified Network.GRPC.LowLevel.Server.Unregistered as U
|
||
|
import qualified Network.GRPC.LowLevel.Call.Unregistered as U
|
||
|
|
||
|
dispatchLoop :: Server
|
||
|
-> [Handler 'Normal]
|
||
|
-> [Handler 'ClientStreaming]
|
||
|
-> [Handler 'ServerStreaming]
|
||
|
-> [Handler 'BiDiStreaming]
|
||
|
-> IO ()
|
||
|
dispatchLoop server hN hC hS hB =
|
||
|
forever $ U.withServerCallAsync server $ \call -> do
|
||
|
case findHandler call allHandlers of
|
||
|
Just (AnyHandler (UnaryHandler _ h)) -> unaryHandler call h
|
||
|
Just (AnyHandler (ClientStreamHandler _ h)) -> csHandler call h
|
||
|
Just (AnyHandler (ServerStreamHandler _ h)) -> ssHandler call h
|
||
|
Just (AnyHandler (BiDiStreamHandler _ h)) -> bdHandler call h
|
||
|
Nothing -> unknownHandler call
|
||
|
where allHandlers = map AnyHandler hN
|
||
|
++ map AnyHandler hC
|
||
|
++ map AnyHandler hS
|
||
|
++ map AnyHandler hB
|
||
|
findHandler call = find ((== (U.callMethod call))
|
||
|
. anyHandlerMethodName)
|
||
|
unknownHandler call =
|
||
|
void $ U.serverHandleNormalCall' server call mempty $ \_ _ ->
|
||
|
return (mempty
|
||
|
, mempty
|
||
|
, StatusNotFound
|
||
|
, StatusDetails "unknown method")
|
||
|
handleError f = f >>= handleCallError
|
||
|
unaryHandler :: (Message a, Message b) =>
|
||
|
U.ServerCall
|
||
|
-> ServerHandler' a b
|
||
|
-> IO ()
|
||
|
unaryHandler call h =
|
||
|
handleError $
|
||
|
U.serverHandleNormalCall' server call mempty $ \call' bs -> do
|
||
|
let h' = convertServerHandler h
|
||
|
h' (fmap (const bs) $ U.convertCall call)
|
||
|
bs
|
||
|
(U.requestMetadataRecv call)
|
||
|
csHandler :: (Message a, Message b) =>
|
||
|
U.ServerCall
|
||
|
-> ServerReaderHandler' a b
|
||
|
-> IO ()
|
||
|
csHandler call h =
|
||
|
handleError $
|
||
|
U.serverReader server call mempty (convertServerReaderHandler h)
|
||
|
ssHandler :: (Message a, Message b) =>
|
||
|
U.ServerCall
|
||
|
-> ServerWriterHandler' a b
|
||
|
-> IO ()
|
||
|
ssHandler call h =
|
||
|
handleError $
|
||
|
U.serverWriter server call mempty (convertServerWriterHandler h)
|
||
|
bdHandler :: (Message a, Message b) =>
|
||
|
U.ServerCall
|
||
|
-> ServerRWHandler' a b
|
||
|
-> IO ()
|
||
|
bdHandler call h =
|
||
|
handleError $
|
||
|
U.serverRW server call mempty (convertServerRWHandler h)
|
||
|
|
||
|
serverLoop :: ServerOptions -> IO ()
|
||
|
serverLoop opts@ServerOptions{..} =
|
||
|
withGRPC $ \grpc ->
|
||
|
withServer grpc (mkConfig opts) $ \server -> do
|
||
|
dispatchLoop server
|
||
|
optNormalHandlers
|
||
|
optClientStreamHandlers
|
||
|
optServerStreamHandlers
|
||
|
optBiDiStreamHandlers
|
||
|
where
|
||
|
mkConfig ServerOptions{..} =
|
||
|
ServerConfig
|
||
|
{ host = "localhost"
|
||
|
, port = optServerPort
|
||
|
, methodsToRegisterNormal = []
|
||
|
, methodsToRegisterClientStreaming = []
|
||
|
, methodsToRegisterServerStreaming = []
|
||
|
, methodsToRegisterBiDiStreaming = []
|
||
|
, serverArgs =
|
||
|
([CompressionAlgArg GrpcCompressDeflate | optUseCompression]
|
||
|
++
|
||
|
[UserAgentPrefix optUserAgentPrefix
|
||
|
, UserAgentSuffix optUserAgentSuffix])
|
||
|
}
|