Skip to content

Commit

Permalink
Generalize endpoint in ClientConfig (#151)
Browse files Browse the repository at this point in the history
gRPC library supports DNS as a default name-system, but others are
supported as well:
https://github.com/grpc/grpc/blob/master/doc/naming.md

This PR generalizes `ClientConfig` such that any arbitrary endpoints
are supported instead of only DNS based TCP/IP connections to a
server. The server code is unmodified as that involves lot more work;
it can be considered in a future PR.

This is a breaking change, but clients only require minimal change to
move to the new structure.
  • Loading branch information
rkaippully authored May 25, 2023
1 parent 0b37ef5 commit 53614aa
Show file tree
Hide file tree
Showing 11 changed files with 27 additions and 37 deletions.
2 changes: 1 addition & 1 deletion bench/Bench.hs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ serverOpts =

main :: IO ()
main = bracket startServer stopServer $ const $ withGRPC $ \grpc ->
withClient grpc (ClientConfig "localhost" 50051 [] Nothing Nothing) $ \c -> do
withClient grpc (ClientConfig "localhost:50051" [] Nothing Nothing) $ \c -> do
rmAdd <- clientRegisterMethodNormal c addMethod
rmClientStream <- clientRegisterMethodClientStreaming c addClientStreamMethod
rmServerStream <- clientRegisterMethodServerStreaming c addServerStreamMethod
Expand Down
2 changes: 1 addition & 1 deletion core/grpc-haskell-core.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: grpc-haskell-core
version: 0.4.0
version: 0.5.0
synopsis: Haskell implementation of gRPC layered on shared C library.
homepage: https://github.com/awakenetworks/gRPC-haskell
license: Apache-2.0
Expand Down
20 changes: 8 additions & 12 deletions core/src/Network/GRPC/LowLevel/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ data ClientSSLConfig = ClientSSLConfig

-- | Configuration necessary to set up a client.

data ClientConfig = ClientConfig {clientServerHost :: Host,
clientServerPort :: Port,
data ClientConfig = ClientConfig {clientServerEndpoint :: Endpoint,
clientArgs :: [C.Arg],
-- ^ Optional arguments for setting up the
-- channel on the client. Supplying an empty
Expand All @@ -74,9 +73,6 @@ data ClientConfig = ClientConfig {clientServerHost :: Host,
-- pseudo-header will be set to the supplied value.
}

clientEndpoint :: ClientConfig -> Endpoint
clientEndpoint ClientConfig{..} = endpoint clientServerHost clientServerPort

addMetadataCreds :: C.ChannelCredentials
-> Maybe C.ClientMetadataCreate
-> IO C.ChannelCredentials
Expand All @@ -86,7 +82,7 @@ addMetadataCreds c (Just create) = do
C.compositeChannelCredentialsCreate c callCreds C.reserved

createChannel :: ClientConfig -> C.GrpcChannelArgs -> IO C.Channel
createChannel conf@ClientConfig{..} chanargs =
createChannel ClientConfig{..} chanargs =
case clientSSLConfig of
Nothing -> C.grpcInsecureChannelCreate e chanargs C.reserved
Just (ClientSSLConfig rootCertPath Nothing plugin) ->
Expand All @@ -101,7 +97,7 @@ createChannel conf@ClientConfig{..} chanargs =
C.withChannelCredentials rootCert privKey clientCert $ \creds -> do
creds' <- addMetadataCreds creds plugin
C.secureChannelCreate creds' e chanargs C.reserved
where (Endpoint e) = clientEndpoint conf
where (Endpoint e) = clientServerEndpoint

createClient :: GRPC -> ClientConfig -> IO Client
createClient grpc clientConfig =
Expand Down Expand Up @@ -138,7 +134,7 @@ clientRegisterMethod :: Client
-> MethodName
-> IO (C.CallHandle)
clientRegisterMethod Client{..} meth = do
let host = fromMaybe (unEndpoint (clientEndpoint clientConfig)) (clientAuthority clientConfig)
let host = fromMaybe (unEndpoint (clientServerEndpoint clientConfig)) (clientAuthority clientConfig)
C.grpcChannelRegisterCall clientChannel
(unMethodName meth)
host
Expand All @@ -149,7 +145,7 @@ clientRegisterMethodNormal :: Client
-> MethodName
-> IO (RegisteredMethod 'Normal)
clientRegisterMethodNormal c meth = do
let e = clientEndpoint (clientConfig c)
let e = clientServerEndpoint (clientConfig c)
h <- clientRegisterMethod c meth
return $ RegisteredMethodNormal meth e h

Expand All @@ -158,15 +154,15 @@ clientRegisterMethodClientStreaming :: Client
-> MethodName
-> IO (RegisteredMethod 'ClientStreaming)
clientRegisterMethodClientStreaming c meth = do
let e = clientEndpoint (clientConfig c)
let e = clientServerEndpoint (clientConfig c)
h <- clientRegisterMethod c meth
return $ RegisteredMethodClientStreaming meth e h

clientRegisterMethodServerStreaming :: Client
-> MethodName
-> IO (RegisteredMethod 'ServerStreaming)
clientRegisterMethodServerStreaming c meth = do
let e = clientEndpoint (clientConfig c)
let e = clientServerEndpoint (clientConfig c)
h <- clientRegisterMethod c meth
return $ RegisteredMethodServerStreaming meth e h

Expand All @@ -175,7 +171,7 @@ clientRegisterMethodBiDiStreaming :: Client
-> MethodName
-> IO (RegisteredMethod 'BiDiStreaming)
clientRegisterMethodBiDiStreaming c meth = do
let e = clientEndpoint (clientConfig c)
let e = clientServerEndpoint (clientConfig c)
h <- clientRegisterMethod c meth
return $ RegisteredMethodBiDiStreaming meth e h

Expand Down
4 changes: 2 additions & 2 deletions core/src/Network/GRPC/LowLevel/Client/Unregistered.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import qualified Network.GRPC.Unsafe.Time as C
import Network.GRPC.LowLevel.Call
import Network.GRPC.LowLevel.Client (Client (..),
NormalRequestResult (..),
clientEndpoint,
clientServerEndpoint,
compileNormalRequestResults)
import Network.GRPC.LowLevel.CompletionQueue (TimeoutSeconds)
import qualified Network.GRPC.LowLevel.CompletionQueue.Unregistered as U
Expand All @@ -34,7 +34,7 @@ clientCreateCall Client{..} meth timeout = do
let parentCall = C.Call nullPtr
C.withDeadlineSeconds timeout $ \deadline -> do
U.channelCreateCall clientChannel parentCall C.propagateDefaults
clientCQ meth (clientEndpoint clientConfig) deadline
clientCQ meth (clientServerEndpoint clientConfig) deadline

withClientCall :: Client
-> MethodName
Expand Down
17 changes: 7 additions & 10 deletions core/tests/LowLevelTests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ testAuthMetadataPropagate = testCase "auth metadata inherited by children" $ do
(Just "tests/ssl/localhost.crt")
Nothing
(Just server1ClientPlugin)),
clientServerPort = 50052
clientServerEndpoint = "localhost:50052"
}

server = do
Expand Down Expand Up @@ -673,7 +673,7 @@ testCustomUserAgent =
where
clientArgs = [UserAgentPrefix "prefix!", UserAgentSuffix "suffix!"]
client =
TestClient (ClientConfig "localhost" 50051 clientArgs Nothing Nothing) $
TestClient (ClientConfig "localhost:50051" clientArgs Nothing Nothing) $
\c -> do rm <- clientRegisterMethodNormal c "/foo"
void $ clientRequest c rm 4 "" mempty
server = TestServer (serverConf (["/foo"],[],[],[])) $ \s -> do
Expand All @@ -694,8 +694,7 @@ testClientCompression =
where
client =
TestClient (ClientConfig
"localhost"
50051
"localhost:50051"
[CompressionAlgArg GrpcCompressDeflate]
Nothing
Nothing) $ \c -> do
Expand All @@ -712,8 +711,7 @@ testClientServerCompression :: TestTree
testClientServerCompression =
csTest' "client/server compression: no errors" client server
where
cconf = ClientConfig "localhost"
50051
cconf = ClientConfig "localhost:50051"
[CompressionAlgArg GrpcCompressDeflate]
Nothing
Nothing
Expand Down Expand Up @@ -743,8 +741,7 @@ testClientServerCompressionLvl :: TestTree
testClientServerCompressionLvl =
csTest' "client/server compression: no errors" client server
where
cconf = ClientConfig "localhost"
50051
cconf = ClientConfig "localhost:50051"
[CompressionLevelArg GrpcCompressLevelHigh]
Nothing
Nothing
Expand Down Expand Up @@ -789,7 +786,7 @@ testClientMaxReceiveMessageLengthChannelArg = do
rm <- clientRegisterMethodNormal c "/foo"
clientRequest c rm 1 pay mempty >>= k
where
conf = ClientConfig "localhost" 50051 [MaxReceiveMessageLength n] Nothing Nothing
conf = ClientConfig "localhost:50051" [MaxReceiveMessageLength n] Nothing Nothing

-- Expect success when the max recv payload size is set to 4 bytes, and we
-- are sent 4.
Expand Down Expand Up @@ -887,7 +884,7 @@ stdTestClient :: (Client -> IO ()) -> TestClient
stdTestClient = TestClient stdClientConf

stdClientConf :: ClientConfig
stdClientConf = ClientConfig "localhost" 50051 [] Nothing Nothing
stdClientConf = ClientConfig "localhost:50051" [] Nothing Nothing

data TestServer = TestServer ServerConfig (Server -> IO ())

Expand Down
2 changes: 1 addition & 1 deletion core/tests/LowLevelTests/Op.hs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ serverConf :: ServerConfig
serverConf = ServerConfig "localhost" 50051 [("/foo")] [] [] [] [] Nothing

clientConf :: ClientConfig
clientConf = ClientConfig "localhost" 50051 [] Nothing Nothing
clientConf = ClientConfig "localhost:50051" [] Nothing Nothing

clientEmptySendOps :: [Op]
clientEmptySendOps =
Expand Down
7 changes: 3 additions & 4 deletions examples/echo/echo-hs/EchoClient.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import qualified Data.Text.Lazy as TL
import Echo
import Network.GRPC.HighLevel.Client
import Network.GRPC.LowLevel
import Network.GRPC.LowLevel.Call (Endpoint(..))
import Options.Generic
import Prelude hiding (FilePath)

data Args = Args
{ bind :: Maybe ByteString <?> "grpc endpoint hostname (default \"localhost\")"
, port :: Maybe Int <?> "grpc endpoint port (default 50051)"
{ endpoint :: Maybe ByteString <?> "grpc endpoint (default \"localhost:50051\")"
, payload :: Maybe TL.Text <?> "string to echo (default \"hullo!\")"
} deriving (Generic, Show)
instance ParseRecord Args
Expand All @@ -32,8 +32,7 @@ main = do
rqt = EchoRequest pay
expected = EchoResponse pay
cfg = ClientConfig
(Host . fromMaybe "localhost" . unHelpful $ bind)
(Port . fromMaybe 50051 . unHelpful $ port)
(Endpoint . fromMaybe "localhost:50051" . unHelpful $ endpoint)
[] Nothing Nothing
withGRPC $ \g -> withClient g cfg $ \c -> do
Echo{..} <- echoClient c
Expand Down
2 changes: 1 addition & 1 deletion examples/hellos/hellos-client/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ doHelloBi c n = do

highlevelMain :: IO ()
highlevelMain = withGRPC $ \g ->
withClient g (ClientConfig "localhost" 50051 [] Nothing Nothing) $ \c -> do
withClient g (ClientConfig "localhost:50051" [] Nothing Nothing) $ \c -> do
let n = 100000
putStrLn "-------------- HelloSS --------------"
doHelloSS c n
Expand Down
3 changes: 1 addition & 2 deletions examples/tutorial/ArithmeticClient.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import Arithmetic
import Network.GRPC.HighLevel.Generated

clientConfig :: ClientConfig
clientConfig = ClientConfig { clientServerHost = "localhost"
, clientServerPort = 50051
clientConfig = ClientConfig { clientServerEndpoint = "localhost:50051"
, clientArgs = []
, clientSSLConfig = Nothing
, clientAuthority = Nothing
Expand Down
3 changes: 1 addition & 2 deletions examples/tutorial/TUTORIAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,7 @@ The client-side code generated for us is `arithmeticClient`, which takes a `Clie

```haskell
clientConfig :: ClientConfig
clientConfig = ClientConfig { clientServerHost = "localhost"
, clientServerPort = 50051
clientConfig = ClientConfig { clientServerEndpoint = "localhost:50051"
, clientArgs = []
, clientSSLConfig = Nothing
, clientAuthority = Nothing
Expand Down
2 changes: 1 addition & 1 deletion tests/TestClient.hs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ main :: IO ()
main = do
threadDelay 10000000
withGRPC $ \grpc ->
withClient grpc (ClientConfig "localhost" 50051 [] Nothing Nothing) $ \client ->
withClient grpc (ClientConfig "localhost:50051" [] Nothing Nothing) $ \client ->
do service <- simpleServiceClient client

(defaultMain $ testGroup "Send gRPC requests"
Expand Down

0 comments on commit 53614aa

Please sign in to comment.