Plumb the `MaxMetadataSize` parameter through to the server (#134)

* Plumb the `maxMetadataSize` parameter through to the server

* Update `proto3-suite` dependency

* Bump proto3-wire to 1.2.2

* Re-generate Echo.hs

* Regenerate `Arithmetic.hs`

* Derp

* Fix codegen

* Update the tests for new codegen

* Patch-bump to `0.2.1`

* Bump to `0.3.0` to indicate a breaking API change...

Suggested by @intractable.
This commit is contained in:
Parnell Springmeyer 2022-02-25 16:23:22 -06:00 committed by GitHub
parent e1091b9c0d
commit 112777023f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 55 additions and 48 deletions

View File

@ -1,5 +1,5 @@
name: grpc-haskell-core name: grpc-haskell-core
version: 0.2.0 version: 0.3.0
synopsis: Haskell implementation of gRPC layered on shared C library. synopsis: Haskell implementation of gRPC layered on shared C library.
homepage: https://github.com/awakenetworks/gRPC-haskell homepage: https://github.com/awakenetworks/gRPC-haskell
license: Apache-2.0 license: Apache-2.0

View File

@ -4,12 +4,12 @@
{-# LANGUAGE GADTs #-} {-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeApplications #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-} {-# OPTIONS_GHC -fno-warn-unused-matches #-}
{-# OPTIONS_GHC -fno-warn-missing-export-lists #-}
-- | Generated by Haskell protocol buffer compiler. DO NOT EDIT! -- | Generated by Haskell protocol buffer compiler. DO NOT EDIT!
module Echo where module Echo where
import qualified Prelude as Hs import qualified Prelude as Hs
import qualified Proto3.Suite.Class as HsProtobuf import qualified Proto3.Suite.Class as HsProtobuf
@ -52,7 +52,7 @@ echoServer ::
echoServer Echo{echoDoEcho = echoDoEcho} echoServer Echo{echoDoEcho = echoDoEcho}
(ServiceOptions serverHost serverPort useCompression (ServiceOptions serverHost serverPort useCompression
userAgentPrefix userAgentSuffix initialMetadata sslConfig logger userAgentPrefix userAgentSuffix initialMetadata sslConfig logger
serverMaxReceiveMessageLength) serverMaxReceiveMessageLength serverMaxMetadataSize)
= (HsGRPC.serverLoop = (HsGRPC.serverLoop
HsGRPC.defaultOptions{HsGRPC.optNormalHandlers = HsGRPC.defaultOptions{HsGRPC.optNormalHandlers =
[(HsGRPC.UnaryHandler (HsGRPC.MethodName "/echo.Echo/DoEcho") [(HsGRPC.UnaryHandler (HsGRPC.MethodName "/echo.Echo/DoEcho")
@ -65,7 +65,8 @@ echoServer Echo{echoDoEcho = echoDoEcho}
optUserAgentSuffix = userAgentSuffix, optUserAgentSuffix = userAgentSuffix,
optInitialMetadata = initialMetadata, optSSLConfig = sslConfig, optInitialMetadata = initialMetadata, optSSLConfig = sslConfig,
optLogger = logger, optLogger = logger,
optMaxReceiveMessageLength = serverMaxReceiveMessageLength}) optMaxReceiveMessageLength = serverMaxReceiveMessageLength,
optMaxMetadataSize = serverMaxMetadataSize})
echoClient :: echoClient ::
HsGRPC.Client -> HsGRPC.Client ->

View File

@ -4,12 +4,12 @@
{-# LANGUAGE GADTs #-} {-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeApplications #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-} {-# OPTIONS_GHC -fno-warn-unused-matches #-}
{-# OPTIONS_GHC -fno-warn-missing-export-lists #-}
-- | Generated by Haskell protocol buffer compiler. DO NOT EDIT! -- | Generated by Haskell protocol buffer compiler. DO NOT EDIT!
module Arithmetic where module Arithmetic where
import qualified Prelude as Hs import qualified Prelude as Hs
import qualified Proto3.Suite.Class as HsProtobuf import qualified Proto3.Suite.Class as HsProtobuf
@ -63,7 +63,7 @@ arithmeticServer
arithmeticRunningSum = arithmeticRunningSum} arithmeticRunningSum = arithmeticRunningSum}
(ServiceOptions serverHost serverPort useCompression (ServiceOptions serverHost serverPort useCompression
userAgentPrefix userAgentSuffix initialMetadata sslConfig logger userAgentPrefix userAgentSuffix initialMetadata sslConfig logger
serverMaxReceiveMessageLength) serverMaxReceiveMessageLength serverMaxMetadataSize)
= (HsGRPC.serverLoop = (HsGRPC.serverLoop
HsGRPC.defaultOptions{HsGRPC.optNormalHandlers = HsGRPC.defaultOptions{HsGRPC.optNormalHandlers =
[(HsGRPC.UnaryHandler [(HsGRPC.UnaryHandler
@ -81,7 +81,8 @@ arithmeticServer
optUserAgentSuffix = userAgentSuffix, optUserAgentSuffix = userAgentSuffix,
optInitialMetadata = initialMetadata, optSSLConfig = sslConfig, optInitialMetadata = initialMetadata, optSSLConfig = sslConfig,
optLogger = logger, optLogger = logger,
optMaxReceiveMessageLength = serverMaxReceiveMessageLength}) optMaxReceiveMessageLength = serverMaxReceiveMessageLength,
optMaxMetadataSize = serverMaxMetadataSize})
arithmeticClient :: arithmeticClient ::
HsGRPC.Client -> HsGRPC.Client ->

View File

@ -1,5 +1,5 @@
name: grpc-haskell name: grpc-haskell
version: 0.2.0 version: 0.3.0
synopsis: Haskell implementation of gRPC layered on shared C library. synopsis: Haskell implementation of gRPC layered on shared C library.
homepage: https://github.com/awakenetworks/gRPC-haskell homepage: https://github.com/awakenetworks/gRPC-haskell
license: Apache-2.0 license: Apache-2.0
@ -29,9 +29,9 @@ library
build-depends: build-depends:
base >=4.8 && <5.0 base >=4.8 && <5.0
, bytestring ==0.10.* , bytestring ==0.10.*
, proto3-suite >=0.4.1 , proto3-suite >=0.4.3
, proto3-wire >=1.2.0 , proto3-wire >=1.2.2
, grpc-haskell-core >=0.2.0 , grpc-haskell-core >=0.2.1
, async >=2.1 && <2.3 , async >=2.1 && <2.3
, managed >= 1.0.5 , managed >= 1.0.5

View File

@ -2,19 +2,20 @@
, base64-bytestring, binary, bytestring, cereal, containers , base64-bytestring, binary, bytestring, cereal, containers
, contravariant, deepseq, doctest, fetchgit, filepath, foldl , contravariant, deepseq, doctest, fetchgit, filepath, foldl
, generic-arbitrary, hashable, haskell-src , generic-arbitrary, hashable, haskell-src
, insert-ordered-containers, lens, mtl, neat-interpolation , insert-ordered-containers, lens, lib, mtl, neat-interpolation
, optparse-applicative, optparse-generic, parsec, parsers, pretty , optparse-applicative, optparse-generic, parsec, parsers, pretty
, pretty-show, proto3-wire, QuickCheck, quickcheck-instances , pretty-show, proto3-wire, QuickCheck, quickcheck-instances
, range-set-list, safe, stdenv, swagger2, system-filepath, tasty , range-set-list, safe, swagger2, system-filepath, tasty
, tasty-hunit, tasty-quickcheck, text, transformers, turtle, vector , tasty-hunit, tasty-quickcheck, text, time, transformers, turtle
, vector
}: }:
mkDerivation { mkDerivation {
pname = "proto3-suite"; pname = "proto3-suite";
version = "0.4.2.0"; version = "0.4.3";
src = fetchgit { src = fetchgit {
url = "https://github.com/awakesecurity/proto3-suite.git"; url = "https://github.com/awakesecurity/proto3-suite.git";
sha256 = "0mpy35r6qd1v5sixhy2lqcn5x81rfj4dc079g1kpa4fb1f23dbha"; sha256 = "0bjqczi6wddxv0n7qmfbrr19ajgq66xdkxx8vfcgbmv8ygma3vlw";
rev = "0af901f9ef3b9719e08eae4fab8fd700d6c8047a"; rev = "7af7d76dcf9cc71ddada3aa4a38abf46f65550ca";
fetchSubmodules = true; fetchSubmodules = true;
}; };
isLibrary = true; isLibrary = true;
@ -26,7 +27,7 @@ mkDerivation {
hashable haskell-src insert-ordered-containers lens mtl hashable haskell-src insert-ordered-containers lens mtl
neat-interpolation parsec parsers pretty pretty-show proto3-wire neat-interpolation parsec parsers pretty pretty-show proto3-wire
QuickCheck quickcheck-instances safe swagger2 system-filepath text QuickCheck quickcheck-instances safe swagger2 system-filepath text
transformers turtle vector time transformers turtle vector
]; ];
executableHaskellDepends = [ executableHaskellDepends = [
base containers mtl optparse-applicative optparse-generic base containers mtl optparse-applicative optparse-generic
@ -38,6 +39,6 @@ mkDerivation {
proto3-wire QuickCheck swagger2 tasty tasty-hunit tasty-quickcheck proto3-wire QuickCheck swagger2 tasty tasty-hunit tasty-quickcheck
text transformers turtle vector text transformers turtle vector
]; ];
description = "A low level library for writing out data in the Protocol Buffers wire format"; description = "A higher-level API to the proto3-wire library";
license = stdenv.lib.licenses.asl20; license = lib.licenses.asl20;
} }

View File

@ -1,17 +1,12 @@
{ mkDerivation, base, bytestring, cereal, containers, deepseq { mkDerivation, base, bytestring, cereal, containers, deepseq
, doctest, fetchgit, ghc-prim, hashable, parameterized, primitive , doctest, ghc-prim, hashable, lib, parameterized, primitive
, QuickCheck, safe, stdenv, tasty, tasty-hunit, tasty-quickcheck , QuickCheck, safe, tasty, tasty-hunit, tasty-quickcheck, text
, text, transformers, unordered-containers, vector , transformers, unordered-containers, vector
}: }:
mkDerivation { mkDerivation {
pname = "proto3-wire"; pname = "proto3-wire";
version = "1.2.0"; version = "1.2.2";
src = fetchgit { sha256 = "8d409536a89a0187f0576711966d2ef45d43acab7b6a3a1c5ee12f6d01adbfb9";
url = "https://github.com/awakesecurity/proto3-wire.git";
sha256 = "062b05ab8icwjxaqrh3wmg8s26m620pigqj3dj6rdx9qas1cq6mi";
rev = "d92ec32ef0f15842b07fb226d8f2d15f36c5fb20";
fetchSubmodules = true;
};
libraryHaskellDepends = [ libraryHaskellDepends = [
base bytestring cereal containers deepseq ghc-prim hashable base bytestring cereal containers deepseq ghc-prim hashable
parameterized primitive QuickCheck safe text transformers parameterized primitive QuickCheck safe text transformers
@ -22,5 +17,5 @@ mkDerivation {
tasty-quickcheck text transformers vector tasty-quickcheck text transformers vector
]; ];
description = "A low-level implementation of the Protocol Buffers (version 3) wire format"; description = "A low-level implementation of the Protocol Buffers (version 3) wire format";
license = stdenv.lib.licenses.asl20; license = lib.licenses.asl20;
} }

View File

@ -80,7 +80,9 @@ data ServiceOptions = ServiceOptions
, logger :: String -> IO () , logger :: String -> IO ()
-- ^ Logging function to use to log errors in handling calls. -- ^ Logging function to use to log errors in handling calls.
, serverMaxReceiveMessageLength :: Maybe Natural , serverMaxReceiveMessageLength :: Maybe Natural
-- ^ Maximum length (in bytes) that the service may receive in a single message -- ^ Maximum length (in bytes) that the service may receive in a single message.
, serverMaxMetadataSize :: Maybe Natural
-- ^ Maximum metadata size (in bytes) that the service may receive in a single request.
} }
defaultServiceOptions :: ServiceOptions defaultServiceOptions :: ServiceOptions
@ -95,6 +97,7 @@ defaultServiceOptions = ServiceOptions
, Network.GRPC.HighLevel.Generated.sslConfig = Nothing , Network.GRPC.HighLevel.Generated.sslConfig = Nothing
, Network.GRPC.HighLevel.Generated.logger = hPutStrLn stderr , Network.GRPC.HighLevel.Generated.logger = hPutStrLn stderr
, Network.GRPC.HighLevel.Generated.serverMaxReceiveMessageLength = Nothing , Network.GRPC.HighLevel.Generated.serverMaxReceiveMessageLength = Nothing
, Network.GRPC.HighLevel.Generated.serverMaxMetadataSize = Nothing
} }
withGRPCClient :: ClientConfig -> (Client -> IO a) -> IO a withGRPCClient :: ClientConfig -> (Client -> IO a) -> IO a

View File

@ -227,6 +227,9 @@ data ServerOptions = ServerOptions
, optLogger :: String -> IO () , optLogger :: String -> IO ()
-- ^ Logging function to use to log errors in handling calls. -- ^ Logging function to use to log errors in handling calls.
, optMaxReceiveMessageLength :: Maybe Natural , optMaxReceiveMessageLength :: Maybe Natural
-- ^ Maximum length (in bytes) that the service may receive in a single message.
, optMaxMetadataSize :: Maybe Natural
-- ^ Maximum metadata size (in bytes) that the service may receive in a single request.
} }
defaultOptions :: ServerOptions defaultOptions :: ServerOptions
@ -244,6 +247,7 @@ defaultOptions = ServerOptions
, optSSLConfig = Nothing , optSSLConfig = Nothing
, optLogger = hPutStrLn stderr , optLogger = hPutStrLn stderr
, optMaxReceiveMessageLength = Nothing , optMaxReceiveMessageLength = Nothing
, optMaxMetadataSize = Nothing
} }
serverLoop :: ServerOptions -> IO () serverLoop :: ServerOptions -> IO ()

View File

@ -124,5 +124,7 @@ serverLoop ServerOptions{..} =
] ]
++ ++
foldMap (pure . MaxReceiveMessageLength) optMaxReceiveMessageLength foldMap (pure . MaxReceiveMessageLength) optMaxReceiveMessageLength
++
foldMap (pure . MaxMetadataSize) optMaxMetadataSize
, sslConfig = optSSLConfig , sslConfig = optSSLConfig
} }

View File

@ -36,7 +36,7 @@ import Test.Tasty.HUnit ((@?=), assertFailure, testCase)
testNormalCall client = testCase "Normal call" $ testNormalCall client = testCase "Normal call" $
do randoms <- fromList <$> replicateM 1000 (randomRIO (1, 1000)) do randoms <- fromList <$> replicateM 1000 (randomRIO (1, 1000))
let req = SimpleServiceRequest "NormalRequest" randoms let req = SimpleServiceRequest "NormalRequest" randoms
res <- simpleServiceNormalCall client res <- simpleServicenormalCall client
(ClientNormalRequest req 10 mempty) (ClientNormalRequest req 10 mempty)
case res of case res of
ClientErrorResponse err -> assertFailure ("ClientErrorResponse: " <> show err) ClientErrorResponse err -> assertFailure ("ClientErrorResponse: " <> show err)
@ -48,7 +48,7 @@ testNormalCall client = testCase "Normal call" $
testClientStreamingCall client = testCase "Client-streaming call" $ testClientStreamingCall client = testCase "Client-streaming call" $
do iterationCount <- randomRIO (5, 50) do iterationCount <- randomRIO (5, 50)
v <- newEmptyMVar v <- newEmptyMVar
res <- simpleServiceClientStreamingCall client . ClientWriterRequest 10 mempty $ \send -> res <- simpleServiceclientStreamingCall client . ClientWriterRequest 10 mempty $ \send ->
do (finalName, totalSum) <- do (finalName, totalSum) <-
fmap ((mconcat *** (sum . mconcat)) . unzip) . fmap ((mconcat *** (sum . mconcat)) . unzip) .
replicateM iterationCount $ replicateM iterationCount $
@ -86,7 +86,7 @@ testServerStreamingCall client = testCase "Server-streaming call" $
do response @?= "Test" do response @?= "Test"
num @?= expNum num @?= expNum
checkResults nums recv checkResults nums recv
res <- simpleServiceServerStreamingCall client $ res <- simpleServiceserverStreamingCall client $
ClientReaderRequest (SimpleServiceRequest "Test" (fromList nums)) 10 mempty ClientReaderRequest (SimpleServiceRequest "Test" (fromList nums)) 10 mempty
(\_ _ -> checkResults nums) (\_ _ -> checkResults nums)
case res of case res of
@ -113,7 +113,7 @@ testBiDiStreamingCall client = testCase "Bidi-streaming call" $
iterations <- randomRIO (50, 500) iterations <- randomRIO (50, 500)
res <- simpleServiceBiDiStreamingCall client $ res <- simpleServicebiDiStreamingCall client $
ClientBiDiRequest 10 mempty (\_ _ -> handleRequests iterations) ClientBiDiRequest 10 mempty (\_ _ -> handleRequests iterations)
case res of case res of
ClientErrorResponse err -> assertFailure ("ClientErrorResponse: " <> show err) ClientErrorResponse err -> assertFailure ("ClientErrorResponse: " <> show err)
@ -132,4 +132,4 @@ main = do
, testClientStreamingCall service , testClientStreamingCall service
, testServerStreamingCall service , testServerStreamingCall service
, testBiDiStreamingCall service ]) `finally` , testBiDiStreamingCall service ]) `finally`
(simpleServiceDone service (ClientNormalRequest SimpleServiceDone 10 mempty)) (simpleServicedone service (ClientNormalRequest SimpleServiceDone 10 mempty))

View File

@ -64,11 +64,11 @@ main :: IO ()
main = do exitVar <- newEmptyMVar main = do exitVar <- newEmptyMVar
forkIO $ simpleServiceServer (SimpleService forkIO $ simpleServiceServer (SimpleService
{ simpleServiceDone = handleDone exitVar { simpleServicedone = handleDone exitVar
, simpleServiceNormalCall = handleNormalCall , simpleServicenormalCall = handleNormalCall
, simpleServiceClientStreamingCall = handleClientStreamingCall , simpleServiceclientStreamingCall = handleClientStreamingCall
, simpleServiceServerStreamingCall = handleServerStreamingCall , simpleServiceserverStreamingCall = handleServerStreamingCall
, simpleServiceBiDiStreamingCall = handleBiDiStreamingCall }) , simpleServicebiDiStreamingCall = handleBiDiStreamingCall })
defaultServiceOptions defaultServiceOptions
takeMVar exitVar takeMVar exitVar