diff --git a/src/GeneralTools/DataverseClient/Client/ConnectionService.cs b/src/GeneralTools/DataverseClient/Client/ConnectionService.cs index 1b91da0..bc3a745 100644 --- a/src/GeneralTools/DataverseClient/Client/ConnectionService.cs +++ b/src/GeneralTools/DataverseClient/Client/ConnectionService.cs @@ -2380,7 +2380,7 @@ internal async Task Command_WebExecuteAsync(string queryStr retry = ShouldRetryWebAPI(ex, retryCount, maxRetryCount, retryPauseTime, out isThrottled); if (retry) { - Utilities.RetryRequest(null, requestTrackingId, TimeSpan.Zero, logDt, logEntry, SessionTrackingId, disableConnectionLocking, _retryPauseTimeRunning, ex, errorStringCheck, ref retryCount, isThrottled, webUriReq: $"{method} {queryString}"); + retryCount = await Utilities.RetryRequest(null, requestTrackingId, TimeSpan.Zero, logDt, logEntry, SessionTrackingId, disableConnectionLocking, _retryPauseTimeRunning, ex, errorStringCheck, retryCount, isThrottled, webUriReq: $"{method} {queryString}").ConfigureAwait(false); } else { diff --git a/src/GeneralTools/DataverseClient/Client/Microsoft.PowerPlatform.Dataverse.Client.csproj b/src/GeneralTools/DataverseClient/Client/Microsoft.PowerPlatform.Dataverse.Client.csproj index 9203b93..eebfc46 100644 --- a/src/GeneralTools/DataverseClient/Client/Microsoft.PowerPlatform.Dataverse.Client.csproj +++ b/src/GeneralTools/DataverseClient/Client/Microsoft.PowerPlatform.Dataverse.Client.csproj @@ -1,52 +1,55 @@ - - Microsoft.PowerPlatform.Dataverse.Client - DataverseClient - true - true - - + + Microsoft.PowerPlatform.Dataverse.Client + DataverseClient + true + true + + - - false - $(OutDir)\Microsoft.PowerPlatform.Dataverse.Client.xml - 6.0 - + + false + $(OutDir)\Microsoft.PowerPlatform.Dataverse.Client.xml + 6.0 + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + - - - + + + diff --git a/src/GeneralTools/DataverseClient/Client/ServiceClient.cs b/src/GeneralTools/DataverseClient/Client/ServiceClient.cs index d2bd013..02c0a40 100644 --- a/src/GeneralTools/DataverseClient/Client/ServiceClient.cs +++ b/src/GeneralTools/DataverseClient/Client/ServiceClient.cs @@ -1871,7 +1871,7 @@ internal async Task Command_ExecuteAsyncImpl(OrganizationR retry = ShouldRetry(req, ex, retryCount, out isThrottled); if (retry) { - Utilities.RetryRequest(req, requestTrackingId, LockWait, logDt, _logEntry, SessionTrackingId, _disableConnectionLocking, _retryPauseTimeRunning, ex, errorStringCheck, ref retryCount, isThrottled); + retryCount = await Utilities.RetryRequest(req, requestTrackingId, LockWait, logDt, _logEntry, SessionTrackingId, _disableConnectionLocking, _retryPauseTimeRunning, ex, errorStringCheck, retryCount, isThrottled).ConfigureAwait(false); } else { @@ -1978,7 +1978,10 @@ internal OrganizationResponse Command_Execute(OrganizationRequest req, string er retry = ShouldRetry(req, ex, retryCount, out isThrottled); if (retry) { - Utilities.RetryRequest(req, requestTrackingId, LockWait, logDt, _logEntry, SessionTrackingId, _disableConnectionLocking, _retryPauseTimeRunning, ex, errorStringCheck, ref retryCount, isThrottled); + Task.Run(async () => + { + retryCount = await Utilities.RetryRequest(req, requestTrackingId, LockWait, logDt, _logEntry, SessionTrackingId, _disableConnectionLocking, _retryPauseTimeRunning, ex, errorStringCheck, retryCount, isThrottled).ConfigureAwait(false); + }).ConfigureAwait(false).GetAwaiter().GetResult(); } else { diff --git a/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs b/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs index 2ec7fb7..c5a8efd 100644 --- a/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs +++ b/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs @@ -446,14 +446,15 @@ internal static string ConstructWebApiRequestUrl(OrganizationRequest request, Ht /// retryCount /// when set indicated this was caused by a Throttle /// - internal static void RetryRequest(OrganizationRequest req, Guid requestTrackingId, TimeSpan LockWait, Stopwatch logDt, + internal static async Task RetryRequest(OrganizationRequest req, Guid requestTrackingId, TimeSpan LockWait, Stopwatch logDt, DataverseTraceLogger logEntry, Guid? sessionTrackingId, bool disableConnectionLocking, TimeSpan retryPauseTimeRunning, - Exception ex, string errorStringCheck, ref int retryCount, bool isThrottled, string webUriReq = "") + Exception ex, string errorStringCheck, int retryCount, bool isThrottled, string webUriReq = "") { retryCount++; logEntry.LogFailure(req, requestTrackingId, sessionTrackingId, disableConnectionLocking, LockWait, logDt, ex, errorStringCheck, webUriMessageReq: webUriReq); logEntry.LogRetry(retryCount, req, retryPauseTimeRunning, isThrottled: isThrottled); - Task.Delay(retryPauseTimeRunning); + await Task.Delay(retryPauseTimeRunning).ConfigureAwait(false); + return retryCount; } /// diff --git a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/ServiceClientTests.cs b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/ServiceClientTests.cs index d0517a4..98ab40f 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/ServiceClientTests.cs +++ b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/ServiceClientTests.cs @@ -15,6 +15,7 @@ using Microsoft.Xrm.Sdk.Metadata; using Microsoft.Xrm.Sdk.Query; using Moq; +using Newtonsoft.Json.Bson; using System; using System.Collections.Generic; using System.Diagnostics; @@ -752,6 +753,57 @@ public void TestResponseHeaderBehavior() Assert.Equal(defaultDOP, cli.RecommendedDegreesOfParallelism); } + [Fact] + public void RetryOperationTest() + { + Mock orgSvc = null; + Mock fakHttpMethodHander = null; + ServiceClient cli = null; + testSupport.SetupMockAndSupport(out orgSvc, out fakHttpMethodHander, out cli); + + Guid testGuid = Guid.NewGuid(); + + CreateRequest exampleRequest = new CreateRequest(); + exampleRequest.Target = new Entity("account"); + exampleRequest.Target.Attributes.Add("id", testGuid); + + Stopwatch testwatch = Stopwatch.StartNew(); + int retrycount = 0; + + Task.Run(async () => + { + retrycount = await Utilities.RetryRequest(exampleRequest, testGuid, new TimeSpan(0), testwatch, cli._logEntry, null, false, new TimeSpan(0, 0, 1), new Exception("Fake_TEST_MSG"), "test retry logic", retrycount, false, null).ConfigureAwait(false); + }).ConfigureAwait(false).GetAwaiter().GetResult(); + Assert.True(retrycount == 1); + Task.Run(async () => + { + retrycount = await Utilities.RetryRequest(exampleRequest, testGuid, new TimeSpan(0), testwatch, cli._logEntry, null, false, new TimeSpan(0, 0, 1), new Exception("Fake_TEST_MSG"), "test retry logic", retrycount, false, null).ConfigureAwait(false); + }).ConfigureAwait(false).GetAwaiter().GetResult(); + Assert.True(retrycount == 2); + } + + [Fact] + public async void RetryOperationAyncTest() + { + Mock orgSvc = null; + Mock fakHttpMethodHander = null; + ServiceClient cli = null; + testSupport.SetupMockAndSupport(out orgSvc, out fakHttpMethodHander, out cli); + + Guid testGuid = Guid.NewGuid(); + + CreateRequest exampleRequest = new CreateRequest(); + exampleRequest.Target = new Entity("account"); + exampleRequest.Target.Attributes.Add("id", testGuid); + + Stopwatch testwatch = Stopwatch.StartNew(); + int retrycount = 0; + + retrycount = await Utilities.RetryRequest(exampleRequest, testGuid, new TimeSpan(0), testwatch, cli._logEntry, null, false, new TimeSpan(0, 0, 1), new Exception("Fake_TEST_MSG"), "test retry logic", retrycount, false, null).ConfigureAwait(false); + Assert.True(retrycount == 1); + retrycount = await Utilities.RetryRequest(exampleRequest, testGuid, new TimeSpan(0), testwatch, cli._logEntry, null, false, new TimeSpan(0, 0, 1), new Exception("Fake_TEST_MSG"), "test retry logic", retrycount, false, null).ConfigureAwait(false); + Assert.True(retrycount == 2); + } #region LiveConnectedTests diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt index 26058d0..24848c1 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt @@ -7,6 +7,13 @@ Notice: Note: Only AD on FullFramework, OAuth, Certificate, ClientSecret Authentication types are supported at this time. ++CURRENTRELEASEID++ +Fix for Retry hang introduced in 1.1.21: +Dependency Changes: + Added: + System.ServiceModel.Http 4.10.3 + System.ServiceModel.Primitives 4.10.3 + +1.1.21: Updated Core SDK to 9.2.24044.9795 Added new ServiceClient method for creating requests called "RequestBuilder" - will allow you to create a request and customized header, user, and other properties as part of there request generation. Dependency Changes: diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec index 81de30c..f0c0196 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec @@ -59,7 +59,8 @@ - + +