Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reconnect better #280

Merged
merged 6 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/Concordium/Client/GRPC2.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import Lens.Micro.Platform
import Network.GRPC.Client
import Network.GRPC.Client.Helpers hiding (Address)
import Network.GRPC.HTTP2.ProtoLens
import Network.GRPC.HTTP2.Types (GRPCStatusCode (DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED))
import Network.HTTP2.Client (ClientError, ClientIO, ExceptT, HostName, PortNumber, TooMuchConcurrency, runExceptT)
import qualified Web.Cookie as Cookie

Expand Down Expand Up @@ -3465,7 +3466,7 @@ withGRPCCore helper k = do
-- yield False, in case the connection is established by another
-- query from this point until the retry. And thus that client
-- will be used next time.
return (0, Nothing)
return (0, Left Retry)
Just (gen, client) -> do
-- if the MVar is not set then we are free to attempt a new query.
-- If it is set then it means a GOAWAY frame is being handled. We
Expand All @@ -3480,19 +3481,19 @@ withGRPCCore helper k = do
let runRPC =
runExceptT (helper client')
>>= \case
Left err -> Nothing <$ logm ("Network error: " <> fromString (show err)) -- client error
Right (Left err) -> Nothing <$ logm ("Too much concurrency: " <> fromString (show err))
Right (Right x) -> return (Just x)
Left err -> Left Retry <$ logm ("Network error: " <> fromString (show err)) -- client error
Right (Left err) -> Left (DoNotRetry (StatusNotOk (RESOURCE_EXHAUSTED, "Too many concurrent requests."))) <$ logm ("Too much concurrency: " <> fromString (show err))
abizjak marked this conversation as resolved.
Show resolved Hide resolved
Right (Right x) -> return (Right x)
race (race (readMVar mv) (threadDelay (timeoutSeconds * 1000000))) runRPC
>>= \case
Left (Left ()) -> (gen, Nothing) <$ logm "Terminating query because GOAWAY received."
Left (Right ()) -> (gen, Nothing) <$ logm "Terminating query because it timed out."
Left (Left ()) -> (gen, Left Retry) <$ logm "Terminating query because GOAWAY received."
Left (Right ()) -> (gen, Left (DoNotRetry (StatusNotOk (DEADLINE_EXCEEDED, "Query timed out.")))) <$ logm "Terminating query because it timed out."
abizjak marked this conversation as resolved.
Show resolved Hide resolved
Right x -> return (gen, x)
Just () -> return (gen, Nothing) -- fail this round, go again after the client is established.
Just () -> return (gen, Left Retry) -- fail this round, go again after the client is established.
ret <- liftIO tryRun

case ret of
(usedGen, Nothing) -> do
(usedGen, Left Retry) -> do
-- failed, need to establish connection
liftIO (logm "gRPC call failed. Will try to reestablish connection.")
retryNum <- asks retryTimes
Expand Down Expand Up @@ -3536,7 +3537,9 @@ withGRPCCore helper k = do
addHeaders response
return $ k response
else return $ k (RequestFailed "Cannot establish connection to GRPC endpoint.")
(_, Just v) ->
(_, Left (DoNotRetry r)) -> do
return (k r)
(_, Right v) ->
let response = toGRPCResult' v
in do
addHeaders response
Expand Down
12 changes: 9 additions & 3 deletions src/Concordium/Client/Runner/Helper.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Concordium.Client.Runner.Helper (
GRPCOutput (..),
GRPCResponse (..),
GRPCHeaderList,
Retry (..),
) where

import Concordium.Client.Cli (logFatal)
Expand Down Expand Up @@ -117,12 +118,17 @@ toGRPCResult' =
let hs = map (\(hn, hv) -> (CI.mk hn, hv)) hds
in StatusOk (GRPCResponse hs t)

data Retry a
abizjak marked this conversation as resolved.
Show resolved Hide resolved
= Retry
| DoNotRetry (GRPCResult a)

-- | Convert a GRPC helper output to a unified result type.
toGRPCResult :: Maybe (GRPCOutput t) -> GRPCResult t
toGRPCResult :: Either (Retry t) (GRPCOutput t) -> GRPCResult t
toGRPCResult ret =
case ret of
Nothing -> RequestFailed "Cannot connect to GRPC server."
Just v -> toGRPCResult' v
Left Retry -> RequestFailed "Cannot connect to GRPC server."
Left (DoNotRetry r) -> r
Right v -> toGRPCResult' v

printJSON :: (MonadIO m) => Either String Value -> m ()
printJSON v =
Expand Down
Loading