From 3b16814c6ca581c21063fa36a7b7fe6dd22680d9 Mon Sep 17 00:00:00 2001 From: "Matthew D. Groves" Date: Tue, 5 Dec 2023 14:15:30 -0500 Subject: [PATCH 1/3] #1062 adding timeouts to couchbase config --- .../CouchbaseBuilder.cs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Testcontainers.Couchbase/CouchbaseBuilder.cs b/src/Testcontainers.Couchbase/CouchbaseBuilder.cs index d5892a0ee..7610a801b 100644 --- a/src/Testcontainers.Couchbase/CouchbaseBuilder.cs +++ b/src/Testcontainers.Couchbase/CouchbaseBuilder.cs @@ -1,3 +1,5 @@ +using System.Net; + namespace Testcontainers.Couchbase; /// @@ -186,7 +188,7 @@ private async Task ConfigureCouchbaseAsync(IContainer container, CancellationTok await WaitStrategy.WaitUntilAsync(() => WaitUntilNodeIsReady.UntilAsync(container), TimeSpan.FromSeconds(2), TimeSpan.FromMinutes(5), ct) .ConfigureAwait(false); - using (var httpClient = new HttpClient()) + using (var httpClient = new HttpClient(new RetryHandler())) { httpClient.BaseAddress = new UriBuilder(Uri.UriSchemeHttp, container.Hostname, container.GetMappedPublicPort(MgmtPort)).Uri; @@ -540,4 +542,33 @@ public CreateBucketRequest(CouchbaseBucket bucket) Content = new FormUrlEncodedContent(content); } } + + private sealed class RetryHandler : DelegatingHandler + { + private const int MaxRetries = 5; + + public RetryHandler() + : base(new HttpClientHandler()) + { + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + for (var _ = 0; _ < MaxRetries; _++) + { + try + { + return await base.SendAsync(request, cancellationToken) + .ConfigureAwait(false); + } + catch (HttpRequestException) + { + await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken) + .ConfigureAwait(false); + } + } + + throw new Exception($"Unable to configure Couchbase. The HTTP request '{request.RequestUri}' did not complete successfully."); + } + } } \ No newline at end of file From 8f789e1af3494ae925a26de6063471648d0c5f2d Mon Sep 17 00:00:00 2001 From: "Matthew D. Groves" Date: Tue, 5 Dec 2023 14:27:32 -0500 Subject: [PATCH 2/3] removed unnecessary using --- src/Testcontainers.Couchbase/CouchbaseBuilder.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Testcontainers.Couchbase/CouchbaseBuilder.cs b/src/Testcontainers.Couchbase/CouchbaseBuilder.cs index 7610a801b..344b55b7a 100644 --- a/src/Testcontainers.Couchbase/CouchbaseBuilder.cs +++ b/src/Testcontainers.Couchbase/CouchbaseBuilder.cs @@ -1,5 +1,3 @@ -using System.Net; - namespace Testcontainers.Couchbase; /// From bee9f0a2ad4fc7087f61654dc42321684558d703 Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:40:59 +0100 Subject: [PATCH 3/3] docs: Add RetryHandler remarks --- src/Testcontainers.Couchbase/CouchbaseBuilder.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Testcontainers.Couchbase/CouchbaseBuilder.cs b/src/Testcontainers.Couchbase/CouchbaseBuilder.cs index 344b55b7a..c89968f11 100644 --- a/src/Testcontainers.Couchbase/CouchbaseBuilder.cs +++ b/src/Testcontainers.Couchbase/CouchbaseBuilder.cs @@ -541,15 +541,29 @@ public CreateBucketRequest(CouchbaseBucket bucket) } } + /// + /// An HTTP retry handler that sends an HTTP request until it succeeds. + /// + /// + /// Sending an HTTP request to Couchbase's API sometimes fails with the following + /// error: System.Net.Http.HttpIOException: The response ended prematurely (ResponseEnded). + /// The HTTP status code 504 indicates an issue with the Couchbase backend. + /// It is likely that the API is not yet ready to process HTTP requests. + /// Typically, trying it again resolves the issue. + /// private sealed class RetryHandler : DelegatingHandler { private const int MaxRetries = 5; + /// + /// Initializes a new instance of the class. + /// public RetryHandler() : base(new HttpClientHandler()) { } + /// protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { for (var _ = 0; _ < MaxRetries; _++)