From 2e30dd0a2839b669ae6da09e9844a1150ad89741 Mon Sep 17 00:00:00 2001 From: Pallab Paul Date: Thu, 3 Aug 2023 14:16:17 -0700 Subject: [PATCH 1/7] Update PostLedgerEntryOperation retry logic --- .../CHANGELOG.md | 6 +++ .../assets.json | 2 +- .../Azure.Security.ConfidentialLedger.csproj | 2 +- .../src/PostLedgerEntryOperation.cs | 37 ++++++++++++++++--- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md index f29226a512f2..638d37c73a01 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History +## 1.2.0 (2023-08-03) + +### Bugs Fixed + +- Allow some `HttpStatusCode.NotFound` occurrences in `PostLedgerEntryOperation` to account for unexpected loss of session stickiness. These errors may occur when the connected node changes and transactions have not been fully replicated. + ## 1.2.0-beta.1 (Unreleased) ### Features Added diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/assets.json b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/assets.json index 445e1f9bf331..f19574db14f6 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/assets.json +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "net", "TagPrefix": "net/confidentialledger/Azure.Security.ConfidentialLedger", - "Tag": "net/confidentialledger/Azure.Security.ConfidentialLedger_48488df791" + "Tag": "net/confidentialledger/Azure.Security.ConfidentialLedger_5657482b45" } diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/Azure.Security.ConfidentialLedger.csproj b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/Azure.Security.ConfidentialLedger.csproj index 150fe921ab55..8fc08c597c37 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/Azure.Security.ConfidentialLedger.csproj +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/Azure.Security.ConfidentialLedger.csproj @@ -2,7 +2,7 @@ Client SDK for the Azure Confidential Ledger service Azure Confidential Ledger - 1.2.0-beta.1 + 1.2.0 1.1.0 Azure ConfidentialLedger diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs index 372caaefec5e..7e3ce27aa22c 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs @@ -55,12 +55,36 @@ public override Response UpdateStatus(CancellationToken cancellationToken = defa async ValueTask IOperation.UpdateStateAsync(bool async, CancellationToken cancellationToken) { - var statusResponse = async - ? await _client.GetTransactionStatusAsync( - Id, - new RequestContext { CancellationToken = cancellationToken, ErrorOptions = ErrorOptions.NoThrow }) - .ConfigureAwait(false) - : _client.GetTransactionStatus(Id, new RequestContext { CancellationToken = cancellationToken, ErrorOptions = ErrorOptions.NoThrow }); + int retryCount = 0; + Azure.Response statusResponse = null; + while (retryCount < 3) + { + statusResponse = async + ? await _client.GetTransactionStatusAsync( + Id, + new RequestContext { CancellationToken = cancellationToken, ErrorOptions = ErrorOptions.NoThrow }) + .ConfigureAwait(false) + : _client.GetTransactionStatus(Id, new RequestContext { CancellationToken = cancellationToken, ErrorOptions = ErrorOptions.NoThrow }); + + // The transaction may not be found due to unexpected loss of session stickiness. + // This may occur when the connected node changes and transactions have not been fully replicated. + // We will perform retry logic to ensure that we have waited for the transactions to fully replicate before throwing an error. + if (statusResponse.Status == (int)HttpStatusCode.NotFound) + { + ++retryCount; + } + else + { + break; + } + + // Add a 0.5 second delay between retries. + if (async) { + await Task.Delay(500).ConfigureAwait(false); + } else { + Thread.Sleep(500); + } + } if (statusResponse.Status != (int)HttpStatusCode.OK) { @@ -76,6 +100,7 @@ async ValueTask IOperation.UpdateStateAsync(bool async, Cancella { return OperationState.Success(statusResponse); } + return OperationState.Pending(statusResponse); } From 60668b1a1a4397d56c9171eb26ef0fb8328a7a7a Mon Sep 17 00:00:00 2001 From: Pallab Paul Date: Thu, 3 Aug 2023 16:30:40 -0700 Subject: [PATCH 2/7] Update Changelog --- .../Azure.Security.ConfidentialLedger/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md index 638d37c73a01..19e75583c5b7 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md @@ -6,7 +6,7 @@ - Allow some `HttpStatusCode.NotFound` occurrences in `PostLedgerEntryOperation` to account for unexpected loss of session stickiness. These errors may occur when the connected node changes and transactions have not been fully replicated. -## 1.2.0-beta.1 (Unreleased) +## 1.2.0-beta.1 (2022-11-09) ### Features Added From d3def665f84470375caf8dd4f7282a1a6b8cd1c5 Mon Sep 17 00:00:00 2001 From: Pallab Paul Date: Thu, 3 Aug 2023 16:38:27 -0700 Subject: [PATCH 3/7] Update PostLedgerEntryOperation --- .../src/PostLedgerEntryOperation.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs index 7e3ce27aa22c..99af50964b26 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs @@ -79,10 +79,11 @@ async ValueTask IOperation.UpdateStateAsync(bool async, Cancella } // Add a 0.5 second delay between retries. + int delayTimeMs = 500; if (async) { - await Task.Delay(500).ConfigureAwait(false); + await Task.Delay(delayTimeMs).ConfigureAwait(false); } else { - Thread.Sleep(500); + Thread.Sleep(delayTimeMs); } } @@ -100,7 +101,6 @@ async ValueTask IOperation.UpdateStateAsync(bool async, Cancella { return OperationState.Success(statusResponse); } - return OperationState.Pending(statusResponse); } From 96afbe6e20645f45ae78071b8a6251168e478a6f Mon Sep 17 00:00:00 2001 From: Pallab Paul Date: Mon, 14 Aug 2023 11:19:44 -0700 Subject: [PATCH 4/7] Add custom response classifer --- .../src/ConfidentialLedgerClient.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/ConfidentialLedgerClient.cs b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/ConfidentialLedgerClient.cs index 4244c91a866b..f3237af5160f 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/ConfidentialLedgerClient.cs +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/ConfidentialLedgerClient.cs @@ -78,11 +78,19 @@ internal ConfidentialLedgerClient(Uri ledgerEndpoint, TokenCredential credential Array.Empty() : new HttpPipelinePolicy[] { new BearerTokenAuthenticationPolicy(_tokenCredential, AuthorizationScopes) }, transportOptions, - new ResponseClassifier()); + new ConfidentialLedgerResponseClassifier()); _ledgerEndpoint = ledgerEndpoint; _apiVersion = actualOptions.Version; } + internal class ConfidentialLedgerResponseClassifier : ResponseClassifier + { + public override bool IsRetriableResponse(HttpMessage message) + { + return base.IsRetriableResponse(message) || message.Response.Status == 404; + } + } + /// Posts a new entry to the ledger. A collection id may optionally be specified. /// /// Below is the JSON schema for the request and response payloads. From f13d7d44b69be3a6d4e6c280a6da011fe4151f32 Mon Sep 17 00:00:00 2001 From: Pallab Paul Date: Mon, 14 Aug 2023 11:26:45 -0700 Subject: [PATCH 5/7] update changelong --- .../CHANGELOG.md | 2 +- .../src/PostLedgerEntryOperation.cs | 37 +++---------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md index 19e75583c5b7..332ef2c4ac07 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md @@ -4,7 +4,7 @@ ### Bugs Fixed -- Allow some `HttpStatusCode.NotFound` occurrences in `PostLedgerEntryOperation` to account for unexpected loss of session stickiness. These errors may occur when the connected node changes and transactions have not been fully replicated. +- Create a custom ResponseClassifier to allow `HttpStatusCode.NotFound` to be retriable. These errors may occur in the `PostLedgerEntryOperation` due to unexpected loss of session stickiness when the connected node changes and transactions have not been fully replicated. ## 1.2.0-beta.1 (2022-11-09) diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs index 99af50964b26..372caaefec5e 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/PostLedgerEntryOperation.cs @@ -55,37 +55,12 @@ public override Response UpdateStatus(CancellationToken cancellationToken = defa async ValueTask IOperation.UpdateStateAsync(bool async, CancellationToken cancellationToken) { - int retryCount = 0; - Azure.Response statusResponse = null; - while (retryCount < 3) - { - statusResponse = async - ? await _client.GetTransactionStatusAsync( - Id, - new RequestContext { CancellationToken = cancellationToken, ErrorOptions = ErrorOptions.NoThrow }) - .ConfigureAwait(false) - : _client.GetTransactionStatus(Id, new RequestContext { CancellationToken = cancellationToken, ErrorOptions = ErrorOptions.NoThrow }); - - // The transaction may not be found due to unexpected loss of session stickiness. - // This may occur when the connected node changes and transactions have not been fully replicated. - // We will perform retry logic to ensure that we have waited for the transactions to fully replicate before throwing an error. - if (statusResponse.Status == (int)HttpStatusCode.NotFound) - { - ++retryCount; - } - else - { - break; - } - - // Add a 0.5 second delay between retries. - int delayTimeMs = 500; - if (async) { - await Task.Delay(delayTimeMs).ConfigureAwait(false); - } else { - Thread.Sleep(delayTimeMs); - } - } + var statusResponse = async + ? await _client.GetTransactionStatusAsync( + Id, + new RequestContext { CancellationToken = cancellationToken, ErrorOptions = ErrorOptions.NoThrow }) + .ConfigureAwait(false) + : _client.GetTransactionStatus(Id, new RequestContext { CancellationToken = cancellationToken, ErrorOptions = ErrorOptions.NoThrow }); if (statusResponse.Status != (int)HttpStatusCode.OK) { From b1db0b5a28e72839dd781b259a4c204c5a54582b Mon Sep 17 00:00:00 2001 From: Pallab Paul Date: Mon, 14 Aug 2023 14:37:34 -0700 Subject: [PATCH 6/7] update changelog --- .../Azure.Security.ConfidentialLedger/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md index 332ef2c4ac07..e8a6071b6108 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md @@ -4,7 +4,7 @@ ### Bugs Fixed -- Create a custom ResponseClassifier to allow `HttpStatusCode.NotFound` to be retriable. These errors may occur in the `PostLedgerEntryOperation` due to unexpected loss of session stickiness when the connected node changes and transactions have not been fully replicated. +- Create a custom ResponseClassifier to allow `HttpStatusCode.NotFound` to be retriable. These errors may occur in scenarios where there is an unexpected loss of session stickiness when the connected node changes and transactions have not been fully replicated. ## 1.2.0-beta.1 (2022-11-09) From 0742c01329148007d46e2235b4389883d1355873 Mon Sep 17 00:00:00 2001 From: Pallab Paul Date: Mon, 14 Aug 2023 16:25:14 -0700 Subject: [PATCH 7/7] address comments --- .../Azure.Security.ConfidentialLedger/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md index e8a6071b6108..4a961f96fb47 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/CHANGELOG.md @@ -4,7 +4,7 @@ ### Bugs Fixed -- Create a custom ResponseClassifier to allow `HttpStatusCode.NotFound` to be retriable. These errors may occur in scenarios where there is an unexpected loss of session stickiness when the connected node changes and transactions have not been fully replicated. +- Service calls that result in a `HttpStatusCode.NotFound` status will now be retried by default. This is to handle scenarios where there is an unexpected loss of session stickiness when the connected node changes and transactions have not been fully replicated. ## 1.2.0-beta.1 (2022-11-09)