Skip to content

Commit c739c17

Browse files
archerzzm-nash
andauthored
feat(core): implement exponential polling strategy (Azure#27017)
* feat(core): implement exponential polling strategy 1. add `IOperationPollingStrategy` and 2 implementation 1.1 `ConstantPollingStrategy` is for constant polling interval 1.2 `ExponentialPollingStrategy` is for exponential polling interval starting from 1 second up to 32 seconds 2. refactor `OperationInternalBase` and `OperationInternalOfT`: 2.1 replace `DefaultPollingInterval` with `PollingStrategy` 2.2 override implementation of `WaitForCompletionResponseAsync` and `WaitForCompletionAsync`, use interval from `PollingStrategy.PollingInterval` 3. add unit test cases, and update project build dependencies part of Azure#26922 * update according to review comments 1. change interface `IOperationPollingStrategy` to abstract class `OperationPollingStrategy` 1.1 move common logic of `GetServerDelay` into `OperationPollingStrategy` 1.2 change `PollingInterval` to `GetNextWait(response)` to be more specific and fit the new logic 2. change polling sequence of `ExponentialPollingStrategy` to `1, 1, 1, 2, 4 ... 32` 3. consolidate polling logic into `OperationInternalBase.PollingResponseAsync` 4. change implementation of `TestLroOperation.cs` to get rid of dependency on `OperationInternals` which is located in `autorest.csharp` 4.1 I can restore the dependency by doing the similar change like `OperationInternalBase`, but that could be overkill, so I choose a simple change. 5. update test cases and build dependency * split polling strategy logic according to review comments 1. add two polling strategy implementation: `ZeroPollingStrategy` and `RetryAfterPollingStrategy` 1.1 `ZeroPollingStrategy` is for testing purpose (e.g play back test recordings) 1.2 `RetryAfterPollingStrategy` is used when detecting the server side support `retry-after` header, and corresponding logic is removed from `ConstantPollingStrategy` and `ExponentialPollingStrategy`. 2. change constructor of `OperationInternalBase` and its subclasses 2.1 add a polling strategy parameter 2.2 change polling strategy initialization logic, now it will" 2.2.1 first check if there is any `retry-after` header, if so then adopt `RetryAfterPollingStrategy` 2.2.2 then adopt the passed-in polling strategy 2.2.3 fall back to `ConstantPollingStrategy` if none is adopted 2.3 change the interval detemination logic of `WaitForCompletionResponseAsync(TimeSpan, CancellationToken)`. Now we adopt the max value of the passed-in interval and the interval determined by polling strategy. 3. update test cases and build dependencies * update according to review comments 1. move `OperationInternalBase.ChoosePollingStrategy()` to `OperationPollingStrategy` class 2. make `OperationInternalBase.PollingStrategy` private and update test cases 3. update polling strategy implementation 3.1. `ConstantPollingStrategy` will return max value of initial constant interval and the passed-in interval 3.2. `ZeroPollingStrategy` will always return 0 3.3. `ExponentialPollingStrategy` will always return sequence value 3.4. `RetryAfterPollingStrategy1 will return max value of retry-after and passed-in interval 3.5. update test cases 4. add back `OperationInternalBase.DefaultPollInterval` 5. move some common logic into `OperationPollingStrategy` * implement `OperationPoller` 1. add `OperationPoller` and `OperationPoller<T>` as the common polling logic implementation 2. replace the polling logic in `OperationInternalBase`, `Operation` and `OperationOfT`. 3. update build dependencies * wip refactor * remove unused delegate * temp - add back polling interval * renames to represent this is a delay strategy and separate from operations which can be used in many places * renaming polling param * more minor refactoring * comment change * updates for non T in test framework * update test cases * fix zero interval for test recording playback 1. fix a type comparison error when using project reference (lro.BaseType.BaseType is from `Operation` in `Azure.ResourceManager`, not `Azure.Core`) 2. unify the zero interval polling logic, since we've dumped the special zero interval handling in `Operation.GetServerDelay` * add files to make autorest changes * tweak to code for autorest * update dataplance csproj files * missed a couple csproj files * add new files to common lro includes * update common lro files * fix folder for shared files * remove duplicate compiles * update 2 more duplicate compiles * address comments from Azure/autorest.csharp#2000 * update who owns defaulting * Update AutoRest C# version to 3.0.0-beta.20220302.4 * fix polling strategy tests * update latest autorest.csharp 3.0.0-beta.20220303.1 * disable some operation internal tests those tests are not working, because we no longer override `OperationInternalBase.WaitAsync` * update OperationInterceptor.cs 1. more precise reflection on the generic types 2. update `RecordedTestBaseTest` 2.1 update `CustomOperation` due to polling architecture change 2.2 update `WaitForCompletionDoesntWaitDuringPlayback` since in playback mode, `CustomOperation.WaitForCompletionAsync` won't be called. Instead, it's intercepted. So we need to use `DateTimeOffset` to check the interval. * update to tests * update so interceptor works with true or false scenarios for no wait in mgmt plane * fix failure in `TestResourceOperationOrResponseOfT` Move exception throwing into `UpdateStatus` and `UpdateStatusAsync`, since the `WaitForXXX` operation will be intercepted and delegate to `OperatonPoller`. * fix test timeout in `Azure.Communication.PhoneNumbers` 1. add `InstrumentOperation` before `operation.WaitForXXX` 2. remove the zero timespan in playback mode, since the operation interceptor will poll by zero timespan * update api for sync wait methods * update to translation LRO to not prefecth first page * regen desktopvirtualization * add back in cancellation token forwarding * add pr comments Co-authored-by: m-nash <prognash@gmail.com> Co-authored-by: m-nash <64171366+m-nash@users.noreply.github.com>
1 parent 9593bbe commit c739c17

File tree

132 files changed

+2005
-520
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+2005
-520
lines changed

common/ManagementTestShared/Redesign/ManagementRecordedTestBase.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,6 @@ protected ManagementRecordedTestBase(bool isAsync, RecordedTestMode? mode = defa
4242

4343
private void Initialize()
4444
{
45-
if (Mode == RecordedTestMode.Playback)
46-
{
47-
var pollField = typeof(OperationInternals).GetField("<DefaultPollingInterval>k__BackingField", BindingFlags.Static | BindingFlags.NonPublic);
48-
pollField.SetValue(null, TimeSpan.Zero);
49-
}
50-
5145
_waitForCleanup = Mode == RecordedTestMode.Live;
5246
}
5347

@@ -232,6 +226,6 @@ public void OneTimeCleanupResourceGroups()
232226
}
233227

234228
protected override object InstrumentOperation(Type operationType, object operation)
235-
=> InstrumentOperationInternal(operationType, operation, false, new ManagementInterceptor(this));
229+
=> InstrumentOperationInternal(operationType, operation, new ManagementInterceptor(this));
236230
}
237231
}

eng/Directory.Build.Common.targets

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@
194194
<Compile Include="$(AzureCoreSharedSources)OperationInternal.cs" LinkBase="Shared/Core" />
195195
<Compile Include="$(AzureCoreSharedSources)OperationInternalBase.cs" LinkBase="Shared/Core" />
196196
<Compile Include="$(AzureCoreSharedSources)OperationInternalOfT.cs" LinkBase="Shared/Core" />
197+
<Compile Include="$(AzureCoreSharedSources)DelayStrategy.cs" LinkBase="Shared/Core" />
198+
<Compile Include="$(AzureCoreSharedSources)ConstantDelayStrategy.cs" LinkBase="Shared/Core" />
199+
<Compile Include="$(AzureCoreSharedSources)ExponentialDelayStrategy.cs" LinkBase="Shared/Core" />
200+
<Compile Include="$(AzureCoreSharedSources)RetryAfterDelayStrategy.cs" LinkBase="Shared/Core" />
201+
<Compile Include="$(AzureCoreSharedSources)OperationPoller.cs" LinkBase="Shared/Core" />
197202
</ItemGroup>
198203

199204
<!-- *********** Management Client Library Override section ************* -->
@@ -217,6 +222,11 @@
217222
<Compile Include="$(AzureCoreSharedSources)OperationInternal.cs" LinkBase="Shared" />
218223
<Compile Include="$(AzureCoreSharedSources)OperationInternalBase.cs" LinkBase="Shared" />
219224
<Compile Include="$(AzureCoreSharedSources)OperationInternalOfT.cs" LinkBase="Shared" />
225+
<Compile Include="$(AzureCoreSharedSources)DelayStrategy.cs" LinkBase="Shared" />
226+
<Compile Include="$(AzureCoreSharedSources)ConstantDelayStrategy.cs" LinkBase="Shared" />
227+
<Compile Include="$(AzureCoreSharedSources)ExponentialDelayStrategy.cs" LinkBase="Shared" />
228+
<Compile Include="$(AzureCoreSharedSources)RetryAfterDelayStrategy.cs" LinkBase="Shared" />
229+
<Compile Include="$(AzureCoreSharedSources)OperationPoller.cs" LinkBase="Shared" />
220230
</ItemGroup>
221231

222232
<!-- Management Client TEST Project Specific Overrides -->

eng/Packages.Data.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
All should have PrivateAssets="All" set so they don't become package dependencies
152152
-->
153153
<ItemGroup>
154-
<PackageReference Update="Microsoft.Azure.AutoRest.CSharp" Version="3.0.0-beta.20220302.3" PrivateAssets="All" />
154+
<PackageReference Update="Microsoft.Azure.AutoRest.CSharp" Version="3.0.0-beta.20220303.1" PrivateAssets="All" />
155155
<PackageReference Update="Azure.ClientSdk.Analyzers" Version="0.1.1-dev.20220111.2" PrivateAssets="All" />
156156
<PackageReference Update="coverlet.collector" Version="1.3.0" PrivateAssets="All" />
157157
<PackageReference Update="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.1" PrivateAssets="All" />

sdk/appconfiguration/Azure.ResourceManager.AppConfiguration/src/Generated/LongRunningOperation/AppConfigurationArmOperation.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/appconfiguration/Azure.ResourceManager.AppConfiguration/src/Generated/LongRunningOperation/AppConfigurationArmOperationOfT.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/azurestackhci/Azure.ResourceManager.StackHCI/src/Generated/LongRunningOperation/StackHCIArmOperation.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/azurestackhci/Azure.ResourceManager.StackHCI/src/Generated/LongRunningOperation/StackHCIArmOperationOfT.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/cdn/Azure.ResourceManager.Cdn/src/Generated/LongRunningOperation/CdnArmOperation.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/cdn/Azure.ResourceManager.Cdn/src/Generated/LongRunningOperation/CdnArmOperationOfT.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/communication/Azure.Communication.PhoneNumbers/api/Azure.Communication.PhoneNumbers.netstandard2.0.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ protected SearchAvailablePhoneNumbersOperation() { }
184184
public override Azure.Response GetRawResponse() { throw null; }
185185
public override Azure.Response UpdateStatus(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
186186
public override System.Threading.Tasks.ValueTask<Azure.Response> UpdateStatusAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
187+
public override Azure.Response<Azure.Communication.PhoneNumbers.PhoneNumberSearchResult> WaitForCompletion(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
188+
public override Azure.Response<Azure.Communication.PhoneNumbers.PhoneNumberSearchResult> WaitForCompletion(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
187189
public override System.Threading.Tasks.ValueTask<Azure.Response<Azure.Communication.PhoneNumbers.PhoneNumberSearchResult>> WaitForCompletionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
188190
public override System.Threading.Tasks.ValueTask<Azure.Response<Azure.Communication.PhoneNumbers.PhoneNumberSearchResult>> WaitForCompletionAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
189191
}
@@ -197,6 +199,8 @@ protected UpdatePhoneNumberCapabilitiesOperation() { }
197199
public override Azure.Response GetRawResponse() { throw null; }
198200
public override Azure.Response UpdateStatus(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
199201
public override System.Threading.Tasks.ValueTask<Azure.Response> UpdateStatusAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
202+
public override Azure.Response<Azure.Communication.PhoneNumbers.PurchasedPhoneNumber> WaitForCompletion(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
203+
public override Azure.Response<Azure.Communication.PhoneNumbers.PurchasedPhoneNumber> WaitForCompletion(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
200204
public override System.Threading.Tasks.ValueTask<Azure.Response<Azure.Communication.PhoneNumbers.PurchasedPhoneNumber>> WaitForCompletionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
201205
public override System.Threading.Tasks.ValueTask<Azure.Response<Azure.Communication.PhoneNumbers.PurchasedPhoneNumber>> WaitForCompletionAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
202206
}

0 commit comments

Comments
 (0)