http2-client-grpc 0.2.0.1 → 0.3.0.0
raw patch · 2 files changed
+37/−24 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Network.GRPC.Client: streamReply :: (Service s, HasMethod s m, MethodStreamingType s m ~ 'ServerStreaming) => RPC s m -> Compression -> MethodInput s m -> (HeaderList -> Either String (MethodOutput s m) -> IO ()) -> RPCCall (HeaderList, HeaderList)
+ Network.GRPC.Client: streamReply :: (Service s, HasMethod s m, MethodStreamingType s m ~ 'ServerStreaming) => RPC s m -> Compression -> a -> MethodInput s m -> (a -> HeaderList -> MethodOutput s m -> IO a) -> RPCCall (a, HeaderList, HeaderList)
- Network.GRPC.Client: streamRequest :: (Service s, HasMethod s m, MethodStreamingType s m ~ 'ClientStreaming) => RPC s m -> (IO (Compression, Either StreamDone (MethodInput s m))) -> RPCCall (RawReply (MethodOutput s m))
+ Network.GRPC.Client: streamRequest :: (Service s, HasMethod s m, MethodStreamingType s m ~ 'ClientStreaming) => RPC s m -> a -> (a -> IO (Compression, a, Either StreamDone (MethodInput s m))) -> RPCCall (a, RawReply (MethodOutput s m))
Files
- http2-client-grpc.cabal +1/−1
- src/Network/GRPC/Client.hs +36/−23
http2-client-grpc.cabal view
@@ -1,5 +1,5 @@ name: http2-client-grpc-version: 0.2.0.1+version: 0.3.0.0 synopsis: Implement gRPC-over-HTTP2 clients. description: Uses http2-client and proto-lens to generate client code. homepage: https://github.com/lucasdicioccio/http2-client-grpc#readme
src/Network/GRPC/Client.hs view
@@ -140,43 +140,51 @@ streamReply :: (Service s, HasMethod s m, MethodStreamingType s m ~ 'ServerStreaming) => RPC s m+ -- ^ The RPC to call. -> Compression+ -- ^ The compression to use.+ -- TODO: revisit compressions.+ -> a+ -- ^ An initial state. -> MethodInput s m- -> (HeaderList -> Either String (MethodOutput s m) -> IO ())- -> RPCCall (HeaderList, HeaderList)-streamReply rpc compress req handler = RPCCall $ \conn stream isfc osfc -> do+ -- ^ The input.+ -> (a -> HeaderList -> MethodOutput s m -> IO a)+ -- ^ A state-passing handler that is called with the message read.+ -> RPCCall (a, HeaderList, HeaderList)+streamReply rpc compress v0 req handler = RPCCall $ \conn stream isfc osfc -> do let {- loop decode hdrs = _waitEvent stream >>= \case+ loop v1 decode hdrs = _waitEvent stream >>= \case (StreamPushPromiseEvent _ _ _) -> throwIO (InvalidState "push promise") (StreamHeadersEvent _ trls) ->- return (hdrs, trls)+ return (v1, hdrs, trls) (StreamErrorEvent _ _) -> throwIO (InvalidState "stream error") (StreamDataEvent _ dat) -> do _addCredit isfc (ByteString.length dat) _ <- _consumeCredit isfc (ByteString.length dat) _ <- _updateWindow isfc- handleAllChunks hdrs decode dat loop+ handleAllChunks v1 hdrs decode dat loop } in do let ocfc = _outgoingFlowControl conn sendSingleMessage rpc req compress setEndStream conn ocfc stream osfc _waitEvent stream >>= \case StreamHeadersEvent _ hdrs ->- loop (decodeOutput rpc compress) hdrs+ loop v0 (decodeOutput rpc compress) hdrs _ -> throwIO (InvalidState "no headers") where- handleAllChunks hdrs decode dat exitLoop =+ handleAllChunks v1 hdrs decode dat exitLoop = case pushChunk decode dat of- (Done unusedDat _ val) -> do- handler hdrs val- handleAllChunks hdrs (decodeOutput rpc compress) unusedDat exitLoop- failure@(Fail _ _ err) -> do- handler hdrs (fromDecoder failure)- throwIO (StreamReplyDecodingError err)+ (Done unusedDat _ (Right val)) -> do+ v2 <- handler v1 hdrs val+ handleAllChunks v2 hdrs (decodeOutput rpc compress) unusedDat exitLoop+ (Done unusedDat _ (Left err)) -> do+ throwIO (StreamReplyDecodingError $ "done-error: " ++ err)+ (Fail _ _ err) -> do+ throwIO (StreamReplyDecodingError $ "fail-error: " ++ err) partial@(Partial _) ->- exitLoop partial hdrs+ exitLoop v1 partial hdrs data StreamDone = StreamDone @@ -184,20 +192,25 @@ streamRequest :: (Service s, HasMethod s m, MethodStreamingType s m ~ 'ClientStreaming) => RPC s m- -> (IO (Compression, Either StreamDone (MethodInput s m)))- -> RPCCall (RawReply (MethodOutput s m))-streamRequest rpc handler = RPCCall $ \conn stream isfc streamFlowControl ->+ -- ^ RPC to call.+ -> a+ -- ^ An initial state.+ -> (a -> IO (Compression, a, Either StreamDone (MethodInput s m)))+ -- ^ A state-passing action to retrieve the next message to send to the server.+ -> RPCCall (a, RawReply (MethodOutput s m))+streamRequest rpc v0 handler = RPCCall $ \conn stream isfc streamFlowControl -> let ocfc = _outgoingFlowControl conn- go = do- (compress, nextEvent) <- handler+ go v1 = do+ (compress, v2, nextEvent) <- handler v1 case nextEvent of Right msg -> do sendSingleMessage rpc msg compress id conn ocfc stream streamFlowControl- go+ go v2 Left _ -> do sendData conn stream setEndStream ""- waitReply rpc compress stream isfc- in go+ reply <- waitReply rpc compress stream isfc+ pure (v2, reply)+ in go v0 -- | Serialize and send a single message.