Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClientModel prototype: LRO abstractions using subtype approach #44275

Closed
wants to merge 11 commits into from
33 changes: 33 additions & 0 deletions sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,46 @@ protected internal ResultCollection(System.ClientModel.Primitives.PipelineRespon
public abstract System.Collections.Generic.IEnumerator<T> GetEnumerator();
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
public abstract partial class ResultOperation : System.ClientModel.ClientResult
{
protected ResultOperation(string id, System.ClientModel.Primitives.PipelineResponse response) { }
public bool HasCompleted { get { throw null; } protected set { } }
public string Id { get { throw null; } protected set { } }
public abstract System.ClientModel.ClientResult UpdateStatus();
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult> UpdateStatusAsync();
public abstract System.ClientModel.ClientResult WaitForCompletionResult(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.ClientModel.ClientResult WaitForCompletionResult(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult> WaitForCompletionResultAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult> WaitForCompletionResultAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
}
public abstract partial class ResultOperation<T> : System.ClientModel.ResultOperation
{
protected ResultOperation(string id, System.ClientModel.Primitives.PipelineResponse response) : base (default(string), default(System.ClientModel.Primitives.PipelineResponse)) { }
public T? Value { get { throw null; } protected set { } }
public abstract System.ClientModel.ClientResult<T> WaitForCompletion(System.TimeSpan? pollingInterval = default(System.TimeSpan?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult<T>> WaitForCompletionAsync(System.TimeSpan? pollingInterval = default(System.TimeSpan?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
}
public partial class ResultPage<T> : System.ClientModel.ResultCollection<T>
{
internal ResultPage() { }
public string? ContinuationToken { get { throw null; } }
public static System.ClientModel.ResultPage<T> Create(System.Collections.Generic.IEnumerable<T> values, string? continuationToken, System.ClientModel.Primitives.PipelineResponse response) { throw null; }
public override System.Collections.Generic.IEnumerator<T> GetEnumerator() { throw null; }
}
public enum ReturnWhen
{
Started = 0,
Completed = 1,
}
public abstract partial class StatusBasedOperation<TStatus, TValue> : System.ClientModel.ResultOperation<TValue>
{
protected StatusBasedOperation(string id, TStatus status, System.ClientModel.Primitives.PipelineResponse response) : base (default(string), default(System.ClientModel.Primitives.PipelineResponse)) { }
public TStatus Status { get { throw null; } protected set { } }
public abstract void Pause();
public abstract void Resume();
public abstract System.ClientModel.ClientResult<(TStatus Status, TValue? Value)> WaitForStatusUpdate(System.TimeSpan? pollingInterval = default(System.TimeSpan?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult<(TStatus Status, TValue? Value)>> WaitForStatusUpdateAsync(System.TimeSpan? pollingInterval = default(System.TimeSpan?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
}
}
namespace System.ClientModel.Primitives
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,46 @@ protected internal ResultCollection(System.ClientModel.Primitives.PipelineRespon
public abstract System.Collections.Generic.IEnumerator<T> GetEnumerator();
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
public abstract partial class ResultOperation : System.ClientModel.ClientResult
{
protected ResultOperation(string id, System.ClientModel.Primitives.PipelineResponse response) { }
public bool HasCompleted { get { throw null; } protected set { } }
public string Id { get { throw null; } protected set { } }
public abstract System.ClientModel.ClientResult UpdateStatus();
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult> UpdateStatusAsync();
public abstract System.ClientModel.ClientResult WaitForCompletionResult(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.ClientModel.ClientResult WaitForCompletionResult(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult> WaitForCompletionResultAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult> WaitForCompletionResultAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
}
public abstract partial class ResultOperation<T> : System.ClientModel.ResultOperation
{
protected ResultOperation(string id, System.ClientModel.Primitives.PipelineResponse response) : base (default(string), default(System.ClientModel.Primitives.PipelineResponse)) { }
public T? Value { get { throw null; } protected set { } }
public abstract System.ClientModel.ClientResult<T> WaitForCompletion(System.TimeSpan? pollingInterval = default(System.TimeSpan?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult<T>> WaitForCompletionAsync(System.TimeSpan? pollingInterval = default(System.TimeSpan?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
}
public partial class ResultPage<T> : System.ClientModel.ResultCollection<T>
{
internal ResultPage() { }
public string? ContinuationToken { get { throw null; } }
public static System.ClientModel.ResultPage<T> Create(System.Collections.Generic.IEnumerable<T> values, string? continuationToken, System.ClientModel.Primitives.PipelineResponse response) { throw null; }
public override System.Collections.Generic.IEnumerator<T> GetEnumerator() { throw null; }
}
public enum ReturnWhen
{
Started = 0,
Completed = 1,
}
public abstract partial class StatusBasedOperation<TStatus, TValue> : System.ClientModel.ResultOperation<TValue>
{
protected StatusBasedOperation(string id, TStatus status, System.ClientModel.Primitives.PipelineResponse response) : base (default(string), default(System.ClientModel.Primitives.PipelineResponse)) { }
public TStatus Status { get { throw null; } protected set { } }
public abstract void Pause();
public abstract void Resume();
public abstract System.ClientModel.ClientResult<(TStatus Status, TValue? Value)> WaitForStatusUpdate(System.TimeSpan? pollingInterval = default(System.TimeSpan?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.ClientModel.ClientResult<(TStatus Status, TValue? Value)>> WaitForStatusUpdateAsync(System.TimeSpan? pollingInterval = default(System.TimeSpan?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
}
}
namespace System.ClientModel.Primitives
{
Expand Down
42 changes: 42 additions & 0 deletions sdk/core/System.ClientModel/src/Convenience/ResultOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.ClientModel.Primitives;
using System.Threading;
using System.Threading.Tasks;

namespace System.ClientModel;

#pragma warning disable CS1591 // public XML comments
public abstract class ResultOperation : ClientResult
{
protected ResultOperation(string id, PipelineResponse response) : base(response)
{
Id = id;
}

public string Id { get; protected set; }

public bool HasCompleted { get; protected set; }

// TODO: Should we take a cancellationToken, since third-party convenience methods don't?
// TODO: Should we take a RequestOptions?
// i.e. Is the non-T version of this for protocol-level, or only for operations that
// don't have an output value?
public abstract ValueTask<ClientResult> UpdateStatusAsync();

public abstract ClientResult UpdateStatus();

// TODO: what is the use case for these? How do they differ from GetRawResponse() ?
public abstract ValueTask<ClientResult> WaitForCompletionResultAsync(TimeSpan pollingInterval, CancellationToken cancellationToken = default);

public abstract ClientResult WaitForCompletionResult(TimeSpan pollingInterval, CancellationToken cancellationToken = default);

public abstract ValueTask<ClientResult> WaitForCompletionResultAsync(CancellationToken cancellationToken = default);

public abstract ClientResult WaitForCompletionResult(CancellationToken cancellationToken = default);

// TODO: should these be virtual with an internal poller implementation?
// TODO: should we have something like DelayStrategy?
}
#pragma warning restore CS1591 // public XML comments
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.ClientModel.Primitives;
using System.Threading;
using System.Threading.Tasks;

namespace System.ClientModel;

#pragma warning disable CS1591 // public XML comments
public abstract class ResultOperation<T> : ResultOperation
{
protected ResultOperation(string id, PipelineResponse response) : base(id, response)
{
}

public T? Value { get; protected set; }

public abstract ValueTask<ClientResult<T>> WaitForCompletionAsync(TimeSpan? pollingInterval =default, CancellationToken cancellationToken = default);

public abstract ClientResult<T> WaitForCompletion(TimeSpan? pollingInterval = default, CancellationToken cancellationToken = default);
}
#pragma warning restore CS1591 // public XML comments
16 changes: 16 additions & 0 deletions sdk/core/System.ClientModel/src/Convenience/ReturnWhen.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Text;

namespace System.ClientModel;

#pragma warning disable CS1591 // public XML comments
public enum ReturnWhen
{
Started,
Completed
}
#pragma warning restore CS1591 // public XML comments
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.ClientModel.Primitives;
using System.Threading;
using System.Threading.Tasks;

namespace System.ClientModel;

#pragma warning disable CS1591 // public XML comments
public abstract class StatusBasedOperation<TStatus, TValue> : ResultOperation<TValue>
{
protected StatusBasedOperation(string id, TStatus status, PipelineResponse response) : base(id, response)
{
Status = status;
}

public TStatus Status { get; protected set; }

public abstract ValueTask<ClientResult<(TStatus Status, TValue? Value)>> WaitForStatusUpdateAsync(TimeSpan? pollingInterval = default, CancellationToken cancellationToken = default);

public abstract ClientResult<(TStatus Status, TValue? Value)> WaitForStatusUpdate(TimeSpan? pollingInterval = default, CancellationToken cancellationToken = default);

// TODO: Optional APIs to Pause and Resume polling
public abstract void Pause();

public abstract void Resume();
}
#pragma warning restore CS1591 // public XML comments
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.ClientModel;
using System.ClientModel.Primitives;
using Azure.Core.TestFramework;

namespace ClientModel.Tests.Mocks;

public class MockLroClient
{
public virtual ResultOperation<MockJsonModel> GetModelLater(ReturnWhen returnWhen, string content)
{
throw new NotImplementedException();
}

public virtual ClientResult GetModelLater(string content, RequestOptions? options = default)
{
throw new NotImplementedException();
}
}