From 5357c57873d98241050859e0bcf2ee26ddf11211 Mon Sep 17 00:00:00 2001 From: Akshay Mankar Date: Wed, 20 Dec 2023 09:34:58 +0100 Subject: [PATCH 1/2] http2-manager: Expose a function to allow single use connections --- libs/http2-manager/src/HTTP2/Client/Manager.hs | 1 + libs/http2-manager/src/HTTP2/Client/Manager/Internal.hs | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/libs/http2-manager/src/HTTP2/Client/Manager.hs b/libs/http2-manager/src/HTTP2/Client/Manager.hs index 2cf1278061..b163b7fdf0 100644 --- a/libs/http2-manager/src/HTTP2/Client/Manager.hs +++ b/libs/http2-manager/src/HTTP2/Client/Manager.hs @@ -11,6 +11,7 @@ module HTTP2.Client.Manager defaultHttp2Manager, http2ManagerWithSSLCtx, withHTTP2Request, + withHTTP2RequestOnSingleUseConn, connectIfNotAlreadyConnected, ConnectionAlreadyClosed (..), disconnectTarget, diff --git a/libs/http2-manager/src/HTTP2/Client/Manager/Internal.hs b/libs/http2-manager/src/HTTP2/Client/Manager/Internal.hs index 884bc46959..0dd00173c8 100644 --- a/libs/http2-manager/src/HTTP2/Client/Manager/Internal.hs +++ b/libs/http2-manager/src/HTTP2/Client/Manager/Internal.hs @@ -165,6 +165,15 @@ withHTTP2Request mgr target req k = do conn <- getOrMakeConnection mgr target sendRequestWithConnection conn req k +-- | Temporary workaround for https://github.com/kazu-yamamoto/http2/issues/102 +withHTTP2RequestOnSingleUseConn :: Http2Manager -> Target -> HTTP2.Request -> (HTTP2.Response -> IO a) -> IO a +withHTTP2RequestOnSingleUseConn Http2Manager {..} target req k = do + sendReqMVar <- newEmptyMVar + thread <- liftIO . async $ startPersistentHTTP2Connection sslContext target cacheLimit sslRemoveTrailingDot tcpConnectionTimeout sendReqMVar + let newConn = HTTP2Conn thread (putMVar sendReqMVar CloseConnection) sendReqMVar + sendRequestWithConnection newConn req $ \resp -> do + k resp <* disconnect newConn + -- | Connects to a server if it is not already connected, useful when making -- many concurrent requests. This way the first few requests don't have to fight -- for making a connection This way the first few requests don't have to fight From b7b258cda111063759f2fa94a3b675d49d305e3d Mon Sep 17 00:00:00 2001 From: Akshay Mankar Date: Wed, 20 Dec 2023 09:35:28 +0100 Subject: [PATCH 2/2] federator: Do no reuse connections when talking to remotes This comes with performance penalty but its required to get around this bug in the http2 library: https://github.com/kazu-yamamoto/http2/issues/102 --- services/federator/src/Federator/Remote.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/federator/src/Federator/Remote.hs b/services/federator/src/Federator/Remote.hs index 21f1443c78..7f1b880dbe 100644 --- a/services/federator/src/Federator/Remote.hs +++ b/services/federator/src/Federator/Remote.hs @@ -101,7 +101,7 @@ interpretRemote = interpret $ \case resp <- mapError (RemoteError target pathT) . (fromEither @FederatorClientHTTP2Error =<<) . embed $ Codensity $ \k -> E.catches - (H2Manager.withHTTP2Request mgr (True, hostname, fromIntegral port) req' (consumeStreamingResponseWith $ k . Right)) + (H2Manager.withHTTP2RequestOnSingleUseConn mgr (True, hostname, fromIntegral port) req' (consumeStreamingResponseWith $ k . Right)) [ E.Handler $ k . Left, E.Handler $ k . Left . FederatorClientTLSException, E.Handler $ k . Left . FederatorClientHTTP2Exception,