@azure-typespec/http-client-csharp-mgmt 1.0.0-alpha.20250409.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/emitter/emitter.d.ts +4 -0
- package/dist/emitter/emitter.d.ts.map +1 -0
- package/dist/emitter/emitter.js +77 -0
- package/dist/emitter/emitter.js.map +1 -0
- package/dist/emitter/index.d.ts +2 -0
- package/dist/emitter/index.d.ts.map +1 -0
- package/dist/emitter/index.js +4 -0
- package/dist/emitter/index.js.map +1 -0
- package/dist/emitter/resource-type.d.ts +2 -0
- package/dist/emitter/resource-type.d.ts.map +1 -0
- package/dist/emitter/resource-type.js +31 -0
- package/dist/emitter/resource-type.js.map +1 -0
- package/dist/emitter/sdk-context-options.d.ts +3 -0
- package/dist/emitter/sdk-context-options.d.ts.map +1 -0
- package/dist/emitter/sdk-context-options.js +23 -0
- package/dist/emitter/sdk-context-options.js.map +1 -0
- package/dist/generator/Azure.Core.dll +0 -0
- package/dist/generator/Azure.Generator.Mgmt.deps.json +998 -0
- package/dist/generator/Azure.Generator.Mgmt.dll +0 -0
- package/dist/generator/Azure.Generator.Mgmt.pdb +0 -0
- package/dist/generator/Azure.Generator.Mgmt.xml +818 -0
- package/dist/generator/Azure.Generator.dll +0 -0
- package/dist/generator/Azure.Generator.pdb +0 -0
- package/dist/generator/Azure.Generator.xml +163 -0
- package/dist/generator/Azure.ResourceManager.dll +0 -0
- package/dist/generator/CommandLine.dll +0 -0
- package/dist/generator/Humanizer.dll +0 -0
- package/dist/generator/Microsoft.Bcl.AsyncInterfaces.dll +0 -0
- package/dist/generator/Microsoft.Build.Framework.dll +0 -0
- package/dist/generator/Microsoft.Build.dll +0 -0
- package/dist/generator/Microsoft.CodeAnalysis.CSharp.Workspaces.dll +0 -0
- package/dist/generator/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- package/dist/generator/Microsoft.CodeAnalysis.Workspaces.dll +0 -0
- package/dist/generator/Microsoft.CodeAnalysis.dll +0 -0
- package/dist/generator/Microsoft.Extensions.Logging.Abstractions.dll +0 -0
- package/dist/generator/Microsoft.NET.StringTools.dll +0 -0
- package/dist/generator/Microsoft.TypeSpec.Generator.ClientModel.dll +0 -0
- package/dist/generator/Microsoft.TypeSpec.Generator.Input.dll +0 -0
- package/dist/generator/Microsoft.TypeSpec.Generator.dll +0 -0
- package/dist/generator/Microsoft.TypeSpec.Generator.runtimeconfig.json +12 -0
- package/dist/generator/NuGet.Common.dll +0 -0
- package/dist/generator/NuGet.Configuration.dll +0 -0
- package/dist/generator/NuGet.Frameworks.dll +0 -0
- package/dist/generator/Shared/Core/AppContextSwitchHelper.cs +42 -0
- package/dist/generator/Shared/Core/AsyncLockWithValue.cs +260 -0
- package/dist/generator/Shared/Core/AzureKeyCredentialPolicy.cs +50 -0
- package/dist/generator/Shared/Core/ClientDiagnostics.cs +73 -0
- package/dist/generator/Shared/Core/DiagnosticScope.cs +473 -0
- package/dist/generator/Shared/Core/DiagnosticScopeFactory.cs +104 -0
- package/dist/generator/Shared/Core/FixedDelayWithNoJitterStrategy.cs +26 -0
- package/dist/generator/Shared/Core/HttpMessageSanitizer.cs +198 -0
- package/dist/generator/Shared/Core/IOperationSource.cs +14 -0
- package/dist/generator/Shared/Core/NextLinkOperationImplementation.cs +690 -0
- package/dist/generator/Shared/Core/OperationFinalStateVia.cs +16 -0
- package/dist/generator/Shared/Core/OperationInternal.cs +256 -0
- package/dist/generator/Shared/Core/OperationInternalBase.cs +234 -0
- package/dist/generator/Shared/Core/OperationInternalOfT.cs +422 -0
- package/dist/generator/Shared/Core/OperationPoller.cs +114 -0
- package/dist/generator/Shared/Core/RawRequestUriBuilder.cs +192 -0
- package/dist/generator/Shared/Core/SequentialDelayStrategy.cs +38 -0
- package/dist/generator/Shared/Core/TaskExtensions.cs +313 -0
- package/dist/generator/Shared/Core/VoidValue.cs +10 -0
- package/dist/generator/System.ClientModel.dll +0 -0
- package/dist/generator/System.ComponentModel.Composition.dll +0 -0
- package/dist/generator/System.Composition.AttributedModel.dll +0 -0
- package/dist/generator/System.Composition.Convention.dll +0 -0
- package/dist/generator/System.Composition.Hosting.dll +0 -0
- package/dist/generator/System.Composition.Runtime.dll +0 -0
- package/dist/generator/System.Composition.TypedParts.dll +0 -0
- package/dist/generator/System.Configuration.ConfigurationManager.dll +0 -0
- package/dist/generator/System.Diagnostics.EventLog.dll +0 -0
- package/dist/generator/System.IO.Pipelines.dll +0 -0
- package/dist/generator/System.Memory.Data.dll +0 -0
- package/dist/generator/System.Reflection.MetadataLoadContext.dll +0 -0
- package/dist/generator/System.Security.Cryptography.ProtectedData.dll +0 -0
- package/dist/generator/cs/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/cs/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/cs/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/cs/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/de/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/de/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/de/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/de/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/es/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/es/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/es/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/es/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/fr/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/fr/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/fr/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/fr/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/it/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/it/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/it/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/it/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/ja/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/ja/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/ja/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/ja/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/ko/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/ko/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/ko/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/ko/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/Azure.Core.dll +0 -0
- package/dist/generator/net8.0/Azure.Generator.Mgmt.deps.json +998 -0
- package/dist/generator/net8.0/Azure.Generator.Mgmt.dll +0 -0
- package/dist/generator/net8.0/Azure.Generator.Mgmt.pdb +0 -0
- package/dist/generator/net8.0/Azure.Generator.Mgmt.xml +818 -0
- package/dist/generator/net8.0/Azure.Generator.dll +0 -0
- package/dist/generator/net8.0/Azure.Generator.pdb +0 -0
- package/dist/generator/net8.0/Azure.Generator.xml +163 -0
- package/dist/generator/net8.0/Azure.ResourceManager.dll +0 -0
- package/dist/generator/net8.0/CommandLine.dll +0 -0
- package/dist/generator/net8.0/Humanizer.dll +0 -0
- package/dist/generator/net8.0/Microsoft.Bcl.AsyncInterfaces.dll +0 -0
- package/dist/generator/net8.0/Microsoft.Build.Framework.dll +0 -0
- package/dist/generator/net8.0/Microsoft.Build.dll +0 -0
- package/dist/generator/net8.0/Microsoft.CodeAnalysis.CSharp.Workspaces.dll +0 -0
- package/dist/generator/net8.0/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- package/dist/generator/net8.0/Microsoft.CodeAnalysis.Workspaces.dll +0 -0
- package/dist/generator/net8.0/Microsoft.CodeAnalysis.dll +0 -0
- package/dist/generator/net8.0/Microsoft.Extensions.Logging.Abstractions.dll +0 -0
- package/dist/generator/net8.0/Microsoft.NET.StringTools.dll +0 -0
- package/dist/generator/net8.0/Microsoft.TypeSpec.Generator.ClientModel.dll +0 -0
- package/dist/generator/net8.0/Microsoft.TypeSpec.Generator.Input.dll +0 -0
- package/dist/generator/net8.0/Microsoft.TypeSpec.Generator.dll +0 -0
- package/dist/generator/net8.0/NuGet.Common.dll +0 -0
- package/dist/generator/net8.0/NuGet.Configuration.dll +0 -0
- package/dist/generator/net8.0/NuGet.Frameworks.dll +0 -0
- package/dist/generator/net8.0/Shared/Core/AppContextSwitchHelper.cs +42 -0
- package/dist/generator/net8.0/Shared/Core/AsyncLockWithValue.cs +260 -0
- package/dist/generator/net8.0/Shared/Core/AzureKeyCredentialPolicy.cs +50 -0
- package/dist/generator/net8.0/Shared/Core/ClientDiagnostics.cs +73 -0
- package/dist/generator/net8.0/Shared/Core/DiagnosticScope.cs +473 -0
- package/dist/generator/net8.0/Shared/Core/DiagnosticScopeFactory.cs +104 -0
- package/dist/generator/net8.0/Shared/Core/FixedDelayWithNoJitterStrategy.cs +26 -0
- package/dist/generator/net8.0/Shared/Core/HttpMessageSanitizer.cs +198 -0
- package/dist/generator/net8.0/Shared/Core/IOperationSource.cs +14 -0
- package/dist/generator/net8.0/Shared/Core/NextLinkOperationImplementation.cs +690 -0
- package/dist/generator/net8.0/Shared/Core/OperationFinalStateVia.cs +16 -0
- package/dist/generator/net8.0/Shared/Core/OperationInternal.cs +256 -0
- package/dist/generator/net8.0/Shared/Core/OperationInternalBase.cs +234 -0
- package/dist/generator/net8.0/Shared/Core/OperationInternalOfT.cs +422 -0
- package/dist/generator/net8.0/Shared/Core/OperationPoller.cs +114 -0
- package/dist/generator/net8.0/Shared/Core/RawRequestUriBuilder.cs +192 -0
- package/dist/generator/net8.0/Shared/Core/SequentialDelayStrategy.cs +38 -0
- package/dist/generator/net8.0/Shared/Core/TaskExtensions.cs +313 -0
- package/dist/generator/net8.0/Shared/Core/VoidValue.cs +10 -0
- package/dist/generator/net8.0/System.ClientModel.dll +0 -0
- package/dist/generator/net8.0/System.ComponentModel.Composition.dll +0 -0
- package/dist/generator/net8.0/System.Composition.AttributedModel.dll +0 -0
- package/dist/generator/net8.0/System.Composition.Convention.dll +0 -0
- package/dist/generator/net8.0/System.Composition.Hosting.dll +0 -0
- package/dist/generator/net8.0/System.Composition.Runtime.dll +0 -0
- package/dist/generator/net8.0/System.Composition.TypedParts.dll +0 -0
- package/dist/generator/net8.0/System.Configuration.ConfigurationManager.dll +0 -0
- package/dist/generator/net8.0/System.Diagnostics.EventLog.dll +0 -0
- package/dist/generator/net8.0/System.IO.Pipelines.dll +0 -0
- package/dist/generator/net8.0/System.Memory.Data.dll +0 -0
- package/dist/generator/net8.0/System.Reflection.MetadataLoadContext.dll +0 -0
- package/dist/generator/net8.0/System.Security.Cryptography.ProtectedData.dll +0 -0
- package/dist/generator/net8.0/cs/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/cs/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/cs/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/cs/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/de/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/de/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/de/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/de/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/es/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/es/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/es/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/es/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/fr/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/fr/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/fr/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/fr/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/it/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/it/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/it/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/it/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/ja/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/ja/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/ja/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/ja/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/ko/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/ko/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/ko/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/ko/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/pl/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/pl/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/pl/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/pl/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/pt-BR/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/pt-BR/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/pt-BR/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/ru/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/ru/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/ru/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/ru/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/runtimes/win/lib/net8.0/System.Diagnostics.EventLog.Messages.dll +0 -0
- package/dist/generator/net8.0/runtimes/win/lib/net8.0/System.Diagnostics.EventLog.dll +0 -0
- package/dist/generator/net8.0/tr/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/tr/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/tr/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/tr/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/zh-Hans/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/zh-Hans/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/zh-Hans/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/net8.0/zh-Hant/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/net8.0/zh-Hant/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/net8.0/zh-Hant/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/pl/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/pl/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/pl/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/pl/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/pt-BR/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/pt-BR/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/pt-BR/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/ru/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/ru/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/ru/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/ru/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/runtimes/win/lib/net8.0/System.Diagnostics.EventLog.Messages.dll +0 -0
- package/dist/generator/runtimes/win/lib/net8.0/System.Diagnostics.EventLog.dll +0 -0
- package/dist/generator/tr/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/tr/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/tr/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/tr/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/zh-Hans/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/zh-Hans/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/zh-Hans/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/generator/zh-Hant/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll +0 -0
- package/dist/generator/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
- package/dist/generator/zh-Hant/Microsoft.CodeAnalysis.Workspaces.resources.dll +0 -0
- package/dist/generator/zh-Hant/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/package.json +67 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#nullable enable
|
|
5
|
+
|
|
6
|
+
using System;
|
|
7
|
+
using System.Collections.Generic;
|
|
8
|
+
using System.Threading;
|
|
9
|
+
using System.Threading.Tasks;
|
|
10
|
+
using Azure.Core.Pipeline;
|
|
11
|
+
|
|
12
|
+
namespace Azure.Core
|
|
13
|
+
{
|
|
14
|
+
/// <summary>
|
|
15
|
+
/// A helper class used to build long-running operation instances. In order to use this helper:
|
|
16
|
+
/// <list type="number">
|
|
17
|
+
/// <item>Make sure your LRO implements the <see cref="IOperation{T}"/> interface.</item>
|
|
18
|
+
/// <item>Add a private <see cref="OperationInternal{T}"/> field to your LRO, and instantiate it during construction.</item>
|
|
19
|
+
/// <item>Delegate method calls to the <see cref="OperationInternal{T}"/> implementations.</item>
|
|
20
|
+
/// </list>
|
|
21
|
+
/// Supported members:
|
|
22
|
+
/// <list type="bullet">
|
|
23
|
+
/// <item>
|
|
24
|
+
/// <description><see cref="HasValue"/></description>
|
|
25
|
+
/// </item>
|
|
26
|
+
/// <item>
|
|
27
|
+
/// <description><see cref="OperationInternalBase.HasCompleted"/></description>
|
|
28
|
+
/// </item>
|
|
29
|
+
/// <item>
|
|
30
|
+
/// <description><see cref="Value"/></description>
|
|
31
|
+
/// </item>
|
|
32
|
+
/// <item>
|
|
33
|
+
/// <description><see cref="OperationInternalBase.RawResponse"/>, used for <see cref="Operation.GetRawResponse"/></description>
|
|
34
|
+
/// </item>
|
|
35
|
+
/// <item>
|
|
36
|
+
/// <description><see cref="OperationInternalBase.UpdateStatus"/></description>
|
|
37
|
+
/// </item>
|
|
38
|
+
/// <item>
|
|
39
|
+
/// <description><see cref="OperationInternalBase.UpdateStatusAsync(CancellationToken)"/></description>
|
|
40
|
+
/// </item>
|
|
41
|
+
/// <item>
|
|
42
|
+
/// <description><see cref="WaitForCompletionAsync(CancellationToken)"/></description>
|
|
43
|
+
/// </item>
|
|
44
|
+
/// <item>
|
|
45
|
+
/// <description><see cref="WaitForCompletionAsync(TimeSpan, CancellationToken)"/></description>
|
|
46
|
+
/// </item>
|
|
47
|
+
/// </list>
|
|
48
|
+
/// </summary>
|
|
49
|
+
/// <typeparam name="T">The final result of the long-running operation. Must match the type used in <see cref="Operation{T}"/>.</typeparam>
|
|
50
|
+
#pragma warning disable SA1649 // File name should match first type name
|
|
51
|
+
internal class OperationInternal<T> : OperationInternalBase
|
|
52
|
+
#pragma warning restore SA1649
|
|
53
|
+
{
|
|
54
|
+
private readonly IOperation<T> _operation;
|
|
55
|
+
private readonly AsyncLockWithValue<OperationState<T>> _stateLock;
|
|
56
|
+
private Response _rawResponse;
|
|
57
|
+
|
|
58
|
+
/// <summary>
|
|
59
|
+
/// Initializes a new instance of the <see cref="OperationInternal"/> class in a final successful state.
|
|
60
|
+
/// </summary>
|
|
61
|
+
/// <param name="rawResponse">The final value of <see cref="OperationInternalBase.RawResponse"/>.</param>
|
|
62
|
+
/// <param name="value">The final result of the long-running operation.</param>
|
|
63
|
+
public static OperationInternal<T> Succeeded(Response rawResponse, T value) => new(OperationState<T>.Success(rawResponse, value));
|
|
64
|
+
|
|
65
|
+
/// <summary>
|
|
66
|
+
/// Initializes a new instance of the <see cref="OperationInternal"/> class in a final failed state.
|
|
67
|
+
/// </summary>
|
|
68
|
+
/// <param name="rawResponse">The final value of <see cref="OperationInternalBase.RawResponse"/>.</param>
|
|
69
|
+
/// <param name="operationFailedException">The exception that will be thrown by <c>UpdateStatusAsync</c>.</param>
|
|
70
|
+
public static OperationInternal<T> Failed(Response rawResponse, RequestFailedException operationFailedException) => new(OperationState<T>.Failure(rawResponse, operationFailedException));
|
|
71
|
+
|
|
72
|
+
/// <summary>
|
|
73
|
+
/// Initializes a new instance of the <see cref="OperationInternal{T}"/> class.
|
|
74
|
+
/// </summary>
|
|
75
|
+
/// <param name="operation">The long-running operation making use of this class. Passing "<c>this</c>" is expected.</param>
|
|
76
|
+
/// <param name="clientDiagnostics">Used for diagnostic scope and exception creation. This is expected to be the instance created during the construction of your main client.</param>
|
|
77
|
+
/// <param name="rawResponse">
|
|
78
|
+
/// The initial value of <see cref="OperationInternalBase.RawResponse"/>. Usually, long-running operation objects can be instantiated in two ways:
|
|
79
|
+
/// <list type="bullet">
|
|
80
|
+
/// <item>
|
|
81
|
+
/// When calling a client's "<c>Start<OperationName></c>" method, a service call is made to start the operation, and an <see cref="Operation{T}"/> instance is returned.
|
|
82
|
+
/// In this case, the response received from this service call can be passed here.
|
|
83
|
+
/// </item>
|
|
84
|
+
/// <item>
|
|
85
|
+
/// When a user instantiates an <see cref="Operation{T}"/> directly using a public constructor, there's no previous service call. In this case, passing <c>null</c> is expected.
|
|
86
|
+
/// </item>
|
|
87
|
+
/// </list>
|
|
88
|
+
/// </param>
|
|
89
|
+
/// <param name="operationTypeName">
|
|
90
|
+
/// The type name of the long-running operation making use of this class. Used when creating diagnostic scopes. If left <c>null</c>, the type name will be inferred based on the
|
|
91
|
+
/// parameter <paramref name="operation"/>.
|
|
92
|
+
/// </param>
|
|
93
|
+
/// <param name="scopeAttributes">The attributes to use during diagnostic scope creation.</param>
|
|
94
|
+
/// <param name="fallbackStrategy">The delay strategy when Retry-After header is not present. When it is present, the longer of the two delays will be used.
|
|
95
|
+
/// Default is <see cref="FixedDelayWithNoJitterStrategy"/>.</param>
|
|
96
|
+
public OperationInternal(IOperation<T> operation,
|
|
97
|
+
ClientDiagnostics clientDiagnostics,
|
|
98
|
+
Response rawResponse,
|
|
99
|
+
string? operationTypeName = null,
|
|
100
|
+
IEnumerable<KeyValuePair<string, string>>? scopeAttributes = null,
|
|
101
|
+
DelayStrategy? fallbackStrategy = null)
|
|
102
|
+
: base(clientDiagnostics, operationTypeName ?? operation.GetType().Name, scopeAttributes, fallbackStrategy)
|
|
103
|
+
{
|
|
104
|
+
_operation = operation;
|
|
105
|
+
_rawResponse = rawResponse;
|
|
106
|
+
_stateLock = new AsyncLockWithValue<OperationState<T>>();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
internal OperationInternal(OperationState<T> finalState)
|
|
110
|
+
: base(finalState.RawResponse)
|
|
111
|
+
{
|
|
112
|
+
// FinalOperation represents operation that is in final state and can't be updated.
|
|
113
|
+
// It implements IOperation<T> and throws exception when UpdateStateAsync is called.
|
|
114
|
+
_operation = new FinalOperation();
|
|
115
|
+
_rawResponse = finalState.RawResponse;
|
|
116
|
+
_stateLock = new AsyncLockWithValue<OperationState<T>>(finalState);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public override Response RawResponse => _stateLock.TryGetValue(out var state) ? state.RawResponse : _rawResponse;
|
|
120
|
+
|
|
121
|
+
public override bool HasCompleted => _stateLock.HasValue;
|
|
122
|
+
|
|
123
|
+
/// <summary>
|
|
124
|
+
/// Returns <c>true</c> if the long-running operation completed successfully and has produced a final result.
|
|
125
|
+
/// <example>Usage example:
|
|
126
|
+
/// <code>
|
|
127
|
+
/// public bool HasValue => _operationInternal.HasValue;
|
|
128
|
+
/// </code>
|
|
129
|
+
/// </example>
|
|
130
|
+
/// </summary>
|
|
131
|
+
public bool HasValue => _stateLock.TryGetValue(out var state) && state.HasSucceeded;
|
|
132
|
+
|
|
133
|
+
/// <summary>
|
|
134
|
+
/// The final result of the long-running operation.
|
|
135
|
+
/// <example>Usage example:
|
|
136
|
+
/// <code>
|
|
137
|
+
/// public T Value => _operationInternal.Value;
|
|
138
|
+
/// </code>
|
|
139
|
+
/// </example>
|
|
140
|
+
/// </summary>
|
|
141
|
+
/// <exception cref="InvalidOperationException">Thrown when the operation has not completed yet.</exception>
|
|
142
|
+
/// <exception cref="RequestFailedException">Thrown when the operation has completed with failures.</exception>
|
|
143
|
+
public T Value
|
|
144
|
+
{
|
|
145
|
+
get
|
|
146
|
+
{
|
|
147
|
+
if (_stateLock.TryGetValue(out var state))
|
|
148
|
+
{
|
|
149
|
+
if (state.HasSucceeded)
|
|
150
|
+
{
|
|
151
|
+
return state.Value!;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
throw state.OperationFailedException!;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
throw new InvalidOperationException("The operation has not completed yet.");
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/// <summary>
|
|
161
|
+
/// Periodically calls <see cref="OperationInternalBase.UpdateStatusAsync(CancellationToken)"/> until the long-running operation completes.
|
|
162
|
+
/// After each service call, a retry-after header may be returned to communicate that there is no reason to poll
|
|
163
|
+
/// for status change until the specified time has passed.
|
|
164
|
+
/// Headers supported are: "Retry-After", "retry-after-ms", and "x-ms-retry-after-ms",
|
|
165
|
+
/// <example>Usage example:
|
|
166
|
+
/// <code>
|
|
167
|
+
/// public async ValueTask<Response<T>> WaitForCompletionAsync(CancellationToken cancellationToken) =>
|
|
168
|
+
/// await _operationInternal.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false);
|
|
169
|
+
/// </code>
|
|
170
|
+
/// </example>
|
|
171
|
+
/// </summary>
|
|
172
|
+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
|
|
173
|
+
/// <returns>The last HTTP response received from the server, including the final result of the long-running operation.</returns>
|
|
174
|
+
/// <exception cref="RequestFailedException">Thrown if there's been any issues during the connection, or if the operation has completed with failures.</exception>
|
|
175
|
+
public async ValueTask<Response<T>> WaitForCompletionAsync(CancellationToken cancellationToken)
|
|
176
|
+
=> await WaitForCompletionAsync(async: true, null, cancellationToken).ConfigureAwait(false);
|
|
177
|
+
|
|
178
|
+
/// <summary>
|
|
179
|
+
/// Periodically calls <see cref="OperationInternalBase.UpdateStatusAsync(CancellationToken)"/> until the long-running operation completes. The interval
|
|
180
|
+
/// between calls is defined by the parameter <paramref name="pollingInterval"/>, but it can change based on information returned
|
|
181
|
+
/// from the server. After each service call, a retry-after header may be returned to communicate that there is no reason to poll
|
|
182
|
+
/// for status change until the specified time has passed. In this case, the maximum value between the <paramref name="pollingInterval"/>
|
|
183
|
+
/// parameter and the retry-after header is chosen as the wait interval. Headers supported are: "Retry-After", "retry-after-ms",
|
|
184
|
+
/// and "x-ms-retry-after-ms".
|
|
185
|
+
/// <example>Usage example:
|
|
186
|
+
/// <code>
|
|
187
|
+
/// public async ValueTask<Response<T>> WaitForCompletionAsync(TimeSpan pollingInterval, CancellationToken cancellationToken) =>
|
|
188
|
+
/// await _operationInternal.WaitForCompletionAsync(pollingInterval, cancellationToken).ConfigureAwait(false);
|
|
189
|
+
/// </code>
|
|
190
|
+
/// </example>
|
|
191
|
+
/// </summary>
|
|
192
|
+
/// <param name="pollingInterval">The interval between status requests to the server.</param>
|
|
193
|
+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
|
|
194
|
+
/// <returns>The last HTTP response received from the server, including the final result of the long-running operation.</returns>
|
|
195
|
+
/// <exception cref="RequestFailedException">Thrown if there's been any issues during the connection, or if the operation has completed with failures.</exception>
|
|
196
|
+
public async ValueTask<Response<T>> WaitForCompletionAsync(TimeSpan pollingInterval, CancellationToken cancellationToken)
|
|
197
|
+
=> await WaitForCompletionAsync(async: true, pollingInterval, cancellationToken).ConfigureAwait(false);
|
|
198
|
+
|
|
199
|
+
/// <summary>
|
|
200
|
+
/// Periodically calls <see cref="OperationInternalBase.UpdateStatus(CancellationToken)"/> until the long-running operation completes.
|
|
201
|
+
/// After each service call, a retry-after header may be returned to communicate that there is no reason to poll
|
|
202
|
+
/// for status change until the specified time has passed.
|
|
203
|
+
/// Headers supported are: "Retry-After", "retry-after-ms", and "x-ms-retry-after-ms",
|
|
204
|
+
/// <example>Usage example:
|
|
205
|
+
/// <code>
|
|
206
|
+
/// public async ValueTask<Response<T>> WaitForCompletionAsync(CancellationToken cancellationToken) =>
|
|
207
|
+
/// await _operationInternal.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false);
|
|
208
|
+
/// </code>
|
|
209
|
+
/// </example>
|
|
210
|
+
/// </summary>
|
|
211
|
+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
|
|
212
|
+
/// <returns>The last HTTP response received from the server, including the final result of the long-running operation.</returns>
|
|
213
|
+
/// <exception cref="RequestFailedException">Thrown if there's been any issues during the connection, or if the operation has completed with failures.</exception>
|
|
214
|
+
public Response<T> WaitForCompletion(CancellationToken cancellationToken)
|
|
215
|
+
=> WaitForCompletionAsync(async: false, null, cancellationToken).EnsureCompleted();
|
|
216
|
+
|
|
217
|
+
/// <summary>
|
|
218
|
+
/// Periodically calls <see cref="OperationInternalBase.UpdateStatus(CancellationToken)"/> until the long-running operation completes. The interval
|
|
219
|
+
/// between calls is defined by the <see cref="FixedDelayWithNoJitterStrategy"/>, which takes into account any retry-after header that is returned
|
|
220
|
+
/// from the server.
|
|
221
|
+
/// <example>Usage example:
|
|
222
|
+
/// <code>
|
|
223
|
+
/// public async ValueTask<Response<T>> WaitForCompletionAsync(CancellationToken cancellationToken) =>
|
|
224
|
+
/// await _operationInternal.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false);
|
|
225
|
+
/// </code>
|
|
226
|
+
/// </example>
|
|
227
|
+
/// </summary>
|
|
228
|
+
/// <param name="pollingInterval">The interval between status requests to the server.</param>
|
|
229
|
+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
|
|
230
|
+
/// <returns>The last HTTP response received from the server, including the final result of the long-running operation.</returns>
|
|
231
|
+
/// <exception cref="RequestFailedException">Thrown if there's been any issues during the connection, or if the operation has completed with failures.</exception>
|
|
232
|
+
public Response<T> WaitForCompletion(TimeSpan pollingInterval, CancellationToken cancellationToken)
|
|
233
|
+
=> WaitForCompletionAsync(async: false, pollingInterval, cancellationToken).EnsureCompleted();
|
|
234
|
+
|
|
235
|
+
private async ValueTask<Response<T>> WaitForCompletionAsync(bool async, TimeSpan? pollingInterval, CancellationToken cancellationToken)
|
|
236
|
+
{
|
|
237
|
+
var rawResponse = await WaitForCompletionResponseAsync(async, pollingInterval, _waitForCompletionScopeName, cancellationToken).ConfigureAwait(false);
|
|
238
|
+
return Response.FromValue(Value, rawResponse);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
protected override async ValueTask<Response> UpdateStatusAsync(bool async, CancellationToken cancellationToken)
|
|
242
|
+
{
|
|
243
|
+
// If _stateLock has the final state, lockOrValue will contain that state, and no lock is acquired.
|
|
244
|
+
// If _stateLock doesn't have the state, GetLockOrValueAsync will acquire the lock that will be released when lockOrValue is disposed
|
|
245
|
+
// While _responseLock is used for the whole WaitForCompletionResponseAsync, _stateLock is used for individual calls of UpdateStatusAsync
|
|
246
|
+
using var asyncLock = await _stateLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);
|
|
247
|
+
if (asyncLock.HasValue)
|
|
248
|
+
{
|
|
249
|
+
return GetResponseFromState(asyncLock.Value);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
using var scope = CreateScope(_updateStatusScopeName);
|
|
253
|
+
try
|
|
254
|
+
{
|
|
255
|
+
var state = await _operation.UpdateStateAsync(async, cancellationToken).ConfigureAwait(false);
|
|
256
|
+
if (!state.HasCompleted)
|
|
257
|
+
{
|
|
258
|
+
Interlocked.Exchange(ref _rawResponse, state.RawResponse);
|
|
259
|
+
return state.RawResponse;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!state.HasSucceeded && state.OperationFailedException == null)
|
|
263
|
+
{
|
|
264
|
+
state = OperationState<T>.Failure(state.RawResponse, new RequestFailedException(state.RawResponse));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
asyncLock.SetValue(state);
|
|
268
|
+
return GetResponseFromState(state);
|
|
269
|
+
}
|
|
270
|
+
catch (Exception e)
|
|
271
|
+
{
|
|
272
|
+
scope.Failed(e);
|
|
273
|
+
throw;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private static Response GetResponseFromState(OperationState<T> state)
|
|
278
|
+
{
|
|
279
|
+
if (state.HasSucceeded)
|
|
280
|
+
{
|
|
281
|
+
return state.RawResponse;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
throw state.OperationFailedException!;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private class FinalOperation : IOperation<T>
|
|
288
|
+
{
|
|
289
|
+
public ValueTask<OperationState<T>> UpdateStateAsync(bool async, CancellationToken cancellationToken)
|
|
290
|
+
=> throw new NotSupportedException("The operation has already completed");
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/// <summary>
|
|
295
|
+
/// An interface used by <see cref="OperationInternal{T}"/> for making service calls and updating state. It's expected that
|
|
296
|
+
/// your long-running operation classes implement this interface.
|
|
297
|
+
/// </summary>
|
|
298
|
+
/// <typeparam name="T">The final result of the long-running operation. Must match the type used in <see cref="Operation{T}"/>.</typeparam>
|
|
299
|
+
internal interface IOperation<T>
|
|
300
|
+
{
|
|
301
|
+
/// <summary>
|
|
302
|
+
/// Calls the service and updates the state of the long-running operation. Properties directly handled by the
|
|
303
|
+
/// <see cref="OperationInternal{T}"/> class, such as <see cref="OperationInternalBase.RawResponse"/> or
|
|
304
|
+
/// <see cref="OperationInternal{T}.Value"/>, don't need to be updated. Operation-specific properties, such
|
|
305
|
+
/// as "<c>CreateOn</c>" or "<c>LastModified</c>", must be manually updated by the operation implementing this
|
|
306
|
+
/// method.
|
|
307
|
+
/// <example>Usage example:
|
|
308
|
+
/// <code>
|
|
309
|
+
/// async ValueTask<OperationState<T>> IOperation<T>.UpdateStateAsync(bool async, CancellationToken cancellationToken)<br/>
|
|
310
|
+
/// {<br/>
|
|
311
|
+
/// Response<R> response = async ? <async service call> : <sync service call>;<br/>
|
|
312
|
+
/// if (<operation succeeded>) return OperationState<T>.Success(response.GetRawResponse(), <parse response>);<br/>
|
|
313
|
+
/// if (<operation failed>) return OperationState<T>.Failure(response.GetRawResponse());<br/>
|
|
314
|
+
/// return OperationState<T>.Pending(response.GetRawResponse());<br/>
|
|
315
|
+
/// }
|
|
316
|
+
/// </code>
|
|
317
|
+
/// </example>
|
|
318
|
+
/// </summary>
|
|
319
|
+
/// <param name="async"><c>true</c> if the call should be executed asynchronously. Otherwise, <c>false</c>.</param>
|
|
320
|
+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
|
|
321
|
+
/// <returns>
|
|
322
|
+
/// A structure indicating the current operation state. The <see cref="OperationState{T}"/> structure must be instantiated by one of
|
|
323
|
+
/// its static methods:
|
|
324
|
+
/// <list type="bullet">
|
|
325
|
+
/// <item>Use <see cref="OperationState{T}.Success"/> when the operation has completed successfully.</item>
|
|
326
|
+
/// <item>Use <see cref="OperationState{T}.Failure"/> when the operation has completed with failures.</item>
|
|
327
|
+
/// <item>Use <see cref="OperationState{T}.Pending"/> when the operation has not completed yet.</item>
|
|
328
|
+
/// </list>
|
|
329
|
+
/// </returns>
|
|
330
|
+
ValueTask<OperationState<T>> UpdateStateAsync(bool async, CancellationToken cancellationToken);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/// <summary>
|
|
334
|
+
/// A helper structure passed to <see cref="OperationInternal{T}"/> to indicate the current operation state. This structure must be
|
|
335
|
+
/// instantiated by one of its static methods, depending on the operation state:
|
|
336
|
+
/// <list type="bullet">
|
|
337
|
+
/// <item>Use <see cref="OperationState{T}.Success"/> when the operation has completed successfully.</item>
|
|
338
|
+
/// <item>Use <see cref="OperationState{T}.Failure"/> when the operation has completed with failures.</item>
|
|
339
|
+
/// <item>Use <see cref="OperationState{T}.Pending"/> when the operation has not completed yet.</item>
|
|
340
|
+
/// </list>
|
|
341
|
+
/// </summary>
|
|
342
|
+
/// <typeparam name="T">The final result of the long-running operation. Must match the type used in <see cref="Operation{T}"/>.</typeparam>
|
|
343
|
+
internal readonly struct OperationState<T>
|
|
344
|
+
{
|
|
345
|
+
private OperationState(Response rawResponse, bool hasCompleted, bool hasSucceeded, T? value, RequestFailedException? operationFailedException)
|
|
346
|
+
{
|
|
347
|
+
RawResponse = rawResponse;
|
|
348
|
+
HasCompleted = hasCompleted;
|
|
349
|
+
HasSucceeded = hasSucceeded;
|
|
350
|
+
Value = value;
|
|
351
|
+
OperationFailedException = operationFailedException;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
public Response RawResponse { get; }
|
|
355
|
+
|
|
356
|
+
public bool HasCompleted { get; }
|
|
357
|
+
|
|
358
|
+
public bool HasSucceeded { get; }
|
|
359
|
+
|
|
360
|
+
public T? Value { get; }
|
|
361
|
+
|
|
362
|
+
public RequestFailedException? OperationFailedException { get; }
|
|
363
|
+
|
|
364
|
+
/// <summary>
|
|
365
|
+
/// Instantiates an <see cref="OperationState{T}"/> indicating the operation has completed successfully.
|
|
366
|
+
/// </summary>
|
|
367
|
+
/// <param name="rawResponse">The HTTP response obtained during the status update.</param>
|
|
368
|
+
/// <param name="value">The final result of the long-running operation.</param>
|
|
369
|
+
/// <returns>A new <see cref="OperationState{T}"/> instance.</returns>
|
|
370
|
+
/// <exception cref="ArgumentNullException">Thrown if <paramref name="rawResponse"/> or <paramref name="value"/> is <c>null</c>.</exception>
|
|
371
|
+
public static OperationState<T> Success(Response rawResponse, T value)
|
|
372
|
+
{
|
|
373
|
+
if (rawResponse is null)
|
|
374
|
+
{
|
|
375
|
+
throw new ArgumentNullException(nameof(rawResponse));
|
|
376
|
+
}
|
|
377
|
+
if (value is null)
|
|
378
|
+
{
|
|
379
|
+
throw new ArgumentNullException(nameof(value));
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return new OperationState<T>(rawResponse, true, true, value, default);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/// <summary>
|
|
386
|
+
/// Instantiates an <see cref="OperationState{T}"/> indicating the operation has completed with failures.
|
|
387
|
+
/// </summary>
|
|
388
|
+
/// <param name="rawResponse">The HTTP response obtained during the status update.</param>
|
|
389
|
+
/// <param name="operationFailedException">
|
|
390
|
+
/// The exception to throw from <c>UpdateStatus</c> because of the operation failure. The same exception will be thrown when
|
|
391
|
+
/// <see cref="OperationInternal{T}.Value"/> is called. If left <c>null</c>, a default exception is created based on the
|
|
392
|
+
/// <paramref name="rawResponse"/> parameter.
|
|
393
|
+
/// </param>
|
|
394
|
+
/// <returns>A new <see cref="OperationState{T}"/> instance.</returns>
|
|
395
|
+
/// <exception cref="ArgumentNullException">Thrown if <paramref name="rawResponse"/> is <c>null</c>.</exception>
|
|
396
|
+
public static OperationState<T> Failure(Response rawResponse, RequestFailedException? operationFailedException = null)
|
|
397
|
+
{
|
|
398
|
+
if (rawResponse is null)
|
|
399
|
+
{
|
|
400
|
+
throw new ArgumentNullException(nameof(rawResponse));
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return new OperationState<T>(rawResponse, true, false, default, operationFailedException);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/// <summary>
|
|
407
|
+
/// Instantiates an <see cref="OperationState{T}"/> indicating the operation has not completed yet.
|
|
408
|
+
/// </summary>
|
|
409
|
+
/// <param name="rawResponse">The HTTP response obtained during the status update.</param>
|
|
410
|
+
/// <returns>A new <see cref="OperationState{T}"/> instance.</returns>
|
|
411
|
+
/// <exception cref="ArgumentNullException">Thrown if <paramref name="rawResponse"/> is <c>null</c>.</exception>
|
|
412
|
+
public static OperationState<T> Pending(Response rawResponse)
|
|
413
|
+
{
|
|
414
|
+
if (rawResponse is null)
|
|
415
|
+
{
|
|
416
|
+
throw new ArgumentNullException(nameof(rawResponse));
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return new OperationState<T>(rawResponse, false, default, default, default);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#nullable enable
|
|
5
|
+
|
|
6
|
+
using System;
|
|
7
|
+
using System.Threading;
|
|
8
|
+
using System.Threading.Tasks;
|
|
9
|
+
using Azure.Core.Pipeline;
|
|
10
|
+
|
|
11
|
+
namespace Azure.Core
|
|
12
|
+
{
|
|
13
|
+
/// <summary>
|
|
14
|
+
/// Implementation of LRO polling logic.
|
|
15
|
+
/// </summary>
|
|
16
|
+
internal sealed class OperationPoller
|
|
17
|
+
{
|
|
18
|
+
private readonly DelayStrategy _delayStrategy;
|
|
19
|
+
|
|
20
|
+
public OperationPoller(DelayStrategy? strategy = null)
|
|
21
|
+
{
|
|
22
|
+
_delayStrategy = strategy ?? new FixedDelayWithNoJitterStrategy();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public ValueTask<Response> WaitForCompletionResponseAsync(Operation operation, TimeSpan? delayHint, CancellationToken cancellationToken)
|
|
26
|
+
=> WaitForCompletionAsync(true, operation, delayHint, cancellationToken);
|
|
27
|
+
|
|
28
|
+
public Response WaitForCompletionResponse(Operation operation, TimeSpan? delayHint, CancellationToken cancellationToken)
|
|
29
|
+
=> WaitForCompletionAsync(false, operation, delayHint, cancellationToken).EnsureCompleted();
|
|
30
|
+
|
|
31
|
+
public ValueTask<Response> WaitForCompletionResponseAsync(OperationInternalBase operation, TimeSpan? delayHint, CancellationToken cancellationToken)
|
|
32
|
+
=> WaitForCompletionAsync(true, operation, delayHint, cancellationToken);
|
|
33
|
+
|
|
34
|
+
public Response WaitForCompletionResponse(OperationInternalBase operation, TimeSpan? delayHint, CancellationToken cancellationToken)
|
|
35
|
+
=> WaitForCompletionAsync(false, operation, delayHint, cancellationToken).EnsureCompleted();
|
|
36
|
+
|
|
37
|
+
public async ValueTask<Response<T>> WaitForCompletionAsync<T>(Operation<T> operation, TimeSpan? delayHint, CancellationToken cancellationToken) where T : notnull
|
|
38
|
+
{
|
|
39
|
+
Response response = await WaitForCompletionAsync(true, operation, delayHint, cancellationToken).ConfigureAwait(false);
|
|
40
|
+
return Response.FromValue(operation.Value, response);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public Response<T> WaitForCompletion<T>(Operation<T> operation, TimeSpan? delayHint, CancellationToken cancellationToken) where T : notnull
|
|
44
|
+
{
|
|
45
|
+
Response response = WaitForCompletionAsync(false, operation, delayHint, cancellationToken).EnsureCompleted();
|
|
46
|
+
return Response.FromValue(operation.Value, response);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public async ValueTask<Response<T>> WaitForCompletionAsync<T>(OperationInternal<T> operation, TimeSpan? delayHint, CancellationToken cancellationToken) where T : notnull
|
|
50
|
+
{
|
|
51
|
+
Response response = await WaitForCompletionAsync(true, operation, delayHint, cancellationToken).ConfigureAwait(false);
|
|
52
|
+
return Response.FromValue(operation.Value, response);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public Response<T> WaitForCompletion<T>(OperationInternal<T> operation, TimeSpan? delayHint, CancellationToken cancellationToken) where T : notnull
|
|
56
|
+
{
|
|
57
|
+
Response response = WaitForCompletionAsync(false, operation, delayHint, cancellationToken).EnsureCompleted();
|
|
58
|
+
return Response.FromValue(operation.Value, response);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private async ValueTask<Response> WaitForCompletionAsync(bool async, Operation operation, TimeSpan? delayHint, CancellationToken cancellationToken)
|
|
62
|
+
{
|
|
63
|
+
int retryNumber = 0;
|
|
64
|
+
while (true)
|
|
65
|
+
{
|
|
66
|
+
Response response = async ? await operation.UpdateStatusAsync(cancellationToken).ConfigureAwait(false) : operation.UpdateStatus(cancellationToken);
|
|
67
|
+
if (operation.HasCompleted)
|
|
68
|
+
{
|
|
69
|
+
return operation.GetRawResponse();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
var strategy = delayHint.HasValue ? new FixedDelayWithNoJitterStrategy(delayHint.Value) : _delayStrategy;
|
|
73
|
+
|
|
74
|
+
await Delay(async, strategy.GetNextDelay(response, ++retryNumber), cancellationToken).ConfigureAwait(false);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private async ValueTask<Response> WaitForCompletionAsync(bool async, OperationInternalBase operation, TimeSpan? delayHint, CancellationToken cancellationToken)
|
|
79
|
+
{
|
|
80
|
+
int retryNumber = 0;
|
|
81
|
+
while (true)
|
|
82
|
+
{
|
|
83
|
+
Response response = async ? await operation.UpdateStatusAsync(cancellationToken).ConfigureAwait(false) : operation.UpdateStatus(cancellationToken);
|
|
84
|
+
if (operation.HasCompleted)
|
|
85
|
+
{
|
|
86
|
+
return operation.RawResponse;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
var strategy = delayHint.HasValue ? new FixedDelayWithNoJitterStrategy(delayHint.Value) : _delayStrategy;
|
|
90
|
+
|
|
91
|
+
await Delay(async, strategy.GetNextDelay(response, ++retryNumber), cancellationToken).ConfigureAwait(false);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private static async ValueTask Delay(bool async, TimeSpan delay, CancellationToken cancellationToken)
|
|
96
|
+
{
|
|
97
|
+
if (async)
|
|
98
|
+
{
|
|
99
|
+
await Task.Delay(delay, cancellationToken).ConfigureAwait(false);
|
|
100
|
+
}
|
|
101
|
+
else if (cancellationToken.CanBeCanceled)
|
|
102
|
+
{
|
|
103
|
+
if (cancellationToken.WaitHandle.WaitOne(delay))
|
|
104
|
+
{
|
|
105
|
+
cancellationToken.ThrowIfCancellationRequested();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else
|
|
109
|
+
{
|
|
110
|
+
Thread.Sleep(delay);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|