Skip to content

Commit b3ca9c7

Browse files
authored
Update DurableTaskClient API to have consistent cancellation tokens (#103)
1 parent c38ca9f commit b3ca9c7

11 files changed

+162
-149
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## v1.0.0
44

55
- Durable Functions class-based syntax now resolves `ITaskActivity` instances from `IServiceProvider`, if available there.
6+
- `DurableTaskClient` methods have been touched up to ensure `CancellationToken` is included, as well as is the last parameter.
67

78
## v1.0.0-rc.1
89

src/Abstractions/Internal/IOrchestrationSubmitter.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,18 @@ public interface IOrchestrationSubmitter
2727
/// The optional input to pass to the scheduled orchestration instance. This must be a serializable value.
2828
/// </param>
2929
/// <param name="options">The options to start the new orchestration with.</param>
30+
/// <param name="cancellation">
31+
/// The cancellation token. This only cancels enqueueing the new orchestration to the backend. Does not cancel the
32+
/// orchestration once enqueued.
33+
/// </param>
3034
/// <returns>
3135
/// A task that completes when the orchestration instance is successfully scheduled. The value of this task is
3236
/// the instance ID of the scheduled orchestration instance. If a non-null instance ID was provided via
3337
/// <paramref name="options" />, the same value will be returned by the completed task.
3438
/// </returns>
3539
Task<string> ScheduleNewOrchestrationInstanceAsync(
36-
TaskName orchestratorName, object? input = null, StartOrchestrationOptions? options = null);
40+
TaskName orchestratorName,
41+
object? input = null,
42+
StartOrchestrationOptions? options = null,
43+
CancellationToken cancellation = default);
3744
}

src/Client/Core/DurableTaskClient.cs

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ protected DurableTaskClient(string name)
4040
/// </summary>
4141
public string Name { get; }
4242

43+
/// <inheritdoc cref="ScheduleNewOrchestrationInstanceAsync(TaskName, object, StartOrchestrationOptions, CancellationToken)"/>
44+
public virtual Task<string> ScheduleNewOrchestrationInstanceAsync(
45+
TaskName orchestratorName, CancellationToken cancellation)
46+
=> this.ScheduleNewOrchestrationInstanceAsync(orchestratorName, null, null, cancellation);
47+
48+
/// <inheritdoc cref="ScheduleNewOrchestrationInstanceAsync(TaskName, object, StartOrchestrationOptions, CancellationToken)"/>
49+
public virtual Task<string> ScheduleNewOrchestrationInstanceAsync(
50+
TaskName orchestratorName, object? input, CancellationToken cancellation)
51+
=> this.ScheduleNewOrchestrationInstanceAsync(orchestratorName, input, null, cancellation);
52+
4353
/// <summary>
4454
/// Schedules a new orchestration instance for execution.
4555
/// </summary>
@@ -58,25 +68,38 @@ protected DurableTaskClient(string name)
5868
/// and health of the backend task hub, and whether a start time was provided via <paramref name="options" />.
5969
/// </para><para>
6070
/// The task associated with this method completes after the orchestration instance was successfully scheduled. You
61-
/// can use the <see cref="GetInstanceMetadataAsync"/> to query the status of the scheduled instance, the
62-
/// <see cref="WaitForInstanceStartAsync"/> method to wait for the instance to transition out of the
63-
/// <see cref="OrchestrationRuntimeStatus.Pending"/> status, or the <see cref="WaitForInstanceCompletionAsync"/>
64-
/// method to wait for the instance to reach a terminal state (Completed, Terminated, Failed, etc.).
71+
/// can use the <see cref="GetInstanceMetadataAsync(string, bool, CancellationToken)"/> to query the status of the
72+
/// scheduled instance, the <see cref="WaitForInstanceStartAsync(string, bool, CancellationToken)"/> method to wait
73+
/// for the instance to transition out of the <see cref="OrchestrationRuntimeStatus.Pending"/> status, or the
74+
/// <see cref="WaitForInstanceCompletionAsync(string, bool, CancellationToken)"/> method to wait for the instance to
75+
/// reach a terminal state (Completed, Terminated, Failed, etc.).
6576
/// </para>
6677
/// </remarks>
6778
/// <param name="orchestratorName">The name of the orchestrator to schedule.</param>
6879
/// <param name="input">
6980
/// The optional input to pass to the scheduled orchestration instance. This must be a serializable value.
7081
/// </param>
7182
/// <param name="options">The options to start the new orchestration with.</param>
83+
/// <param name="cancellation">
84+
/// The cancellation token. This only cancels enqueueing the new orchestration to the backend. Does not cancel the
85+
/// orchestration once enqueued.
86+
/// </param>
7287
/// <returns>
7388
/// A task that completes when the orchestration instance is successfully scheduled. The value of this task is
7489
/// the instance ID of the scheduled orchestration instance. If a non-null instance ID was provided via
7590
/// <paramref name="options" />, the same value will be returned by the completed task.
7691
/// </returns>
7792
/// <exception cref="ArgumentNullException">Thrown if <paramref name="orchestratorName"/> is empty.</exception>
7893
public abstract Task<string> ScheduleNewOrchestrationInstanceAsync(
79-
TaskName orchestratorName, object? input = null, StartOrchestrationOptions? options = null);
94+
TaskName orchestratorName,
95+
object? input = null,
96+
StartOrchestrationOptions? options = null,
97+
CancellationToken cancellation = default);
98+
99+
/// <inheritdoc cref="RaiseEventAsync(string, string, object, CancellationToken)"/>
100+
public virtual Task RaiseEventAsync(
101+
string instanceId, string eventName, CancellationToken cancellation)
102+
=> this.RaiseEventAsync(instanceId, eventName, null, cancellation);
80103

81104
/// <summary>
82105
/// Sends an event notification message to a waiting orchestration instance.
@@ -101,11 +124,21 @@ public abstract Task<string> ScheduleNewOrchestrationInstanceAsync(
101124
/// <param name="instanceId">The ID of the orchestration instance that will handle the event.</param>
102125
/// <param name="eventName">The name of the event. Event names are case-insensitive.</param>
103126
/// <param name="eventPayload">The serializable data payload to include with the event.</param>
127+
/// <param name="cancellation">
128+
/// The cancellation token. This only cancels enqueueing the event to the backend. Does not abort sending the event
129+
/// once enqueued.
130+
/// </param>
104131
/// <returns>A task that completes when the event notification message has been enqueued.</returns>
105132
/// <exception cref="ArgumentNullException">
106133
/// Thrown if <paramref name="instanceId"/> or <paramref name="eventName"/> is null or empty.
107134
/// </exception>
108-
public abstract Task RaiseEventAsync(string instanceId, string eventName, object? eventPayload);
135+
public abstract Task RaiseEventAsync(
136+
string instanceId, string eventName, object? eventPayload = null, CancellationToken cancellation = default);
137+
138+
/// <inheritdoc cref="TerminateAsync(string, object, CancellationToken)"/>
139+
public virtual Task TerminateAsync(
140+
string instanceId, CancellationToken cancellation)
141+
=> this.TerminateAsync(instanceId, null, cancellation);
109142

110143
/// <summary>
111144
/// Terminates a running orchestration instance and updates its runtime status to
@@ -116,7 +149,8 @@ public abstract Task<string> ScheduleNewOrchestrationInstanceAsync(
116149
/// This method internally enqueues a "terminate" message in the task hub. When the task hub worker processes
117150
/// this message, it will update the runtime status of the target instance to
118151
/// <see cref="OrchestrationRuntimeStatus.Terminated"/>. You can use the
119-
/// <see cref="WaitForInstanceCompletionAsync"/> to wait for the instance to reach the terminated state.
152+
/// <see cref="WaitForInstanceCompletionAsync(string, bool, CancellationToken)"/> to wait for the instance to reach
153+
/// the terminated state.
120154
/// </para>
121155
/// <para>
122156
/// Terminating an orchestration instance has no effect on any in-flight activity function executions
@@ -131,8 +165,18 @@ public abstract Task<string> ScheduleNewOrchestrationInstanceAsync(
131165
/// </remarks>
132166
/// <param name="instanceId">The ID of the orchestration instance to terminate.</param>
133167
/// <param name="output">The optional output to set for the terminated orchestration instance.</param>
168+
/// <param name="cancellation">
169+
/// The cancellation token. This only cancels enqueueing the termination request to the backend. Does not abort
170+
/// termination of the orchestration once enqueued.
171+
/// </param>
134172
/// <returns>A task that completes when the terminate message is enqueued.</returns>
135-
public abstract Task TerminateAsync(string instanceId, object? output);
173+
public abstract Task TerminateAsync(
174+
string instanceId, object? output = null, CancellationToken cancellation = default);
175+
176+
/// <inheritdoc cref="WaitForInstanceStartAsync(string, bool, CancellationToken)"/>
177+
public virtual Task<OrchestrationMetadata> WaitForInstanceStartAsync(
178+
string instanceId, CancellationToken cancellation)
179+
=> this.WaitForInstanceStartAsync(instanceId, false, cancellation);
136180

137181
/// <summary>
138182
/// Waits for an orchestration to start running and returns a <see cref="OrchestrationMetadata"/>
@@ -147,22 +191,23 @@ public abstract Task<string> ScheduleNewOrchestrationInstanceAsync(
147191
/// </para>
148192
/// </remarks>
149193
/// <param name="instanceId">The unique ID of the orchestration instance to wait for.</param>
150-
/// <param name="cancellationToken">
151-
/// A <see cref="CancellationToken"/> that can be used to cancel the wait operation.
152-
/// </param>
153194
/// <param name="getInputsAndOutputs">
154195
/// Specify <c>true</c> to fetch the orchestration instance's inputs, outputs, and custom status, or <c>false</c> to
155196
/// omit them. The default value is <c>false</c> to minimize the network bandwidth, serialization, and memory costs
156197
/// associated with fetching the instance metadata.
157198
/// </param>
199+
/// <param name="cancellation">A <see cref="CancellationToken"/> that can be used to cancel the wait operation.</param>
158200
/// <returns>
159201
/// Returns a <see cref="OrchestrationMetadata"/> record that describes the orchestration instance and its execution
160202
/// status or <c>null</c> if no instance with ID <paramref name="instanceId"/> is found.
161203
/// </returns>
162204
public abstract Task<OrchestrationMetadata> WaitForInstanceStartAsync(
163-
string instanceId,
164-
CancellationToken cancellationToken,
165-
bool getInputsAndOutputs = false);
205+
string instanceId, bool getInputsAndOutputs = false, CancellationToken cancellation = default);
206+
207+
/// <inheritdoc cref="WaitForInstanceCompletionAsync(string, bool, CancellationToken)"/>
208+
public virtual Task<OrchestrationMetadata> WaitForInstanceCompletionAsync(
209+
string instanceId, CancellationToken cancellation)
210+
=> this.WaitForInstanceCompletionAsync(instanceId, false, cancellation);
166211

167212
/// <summary>
168213
/// Waits for an orchestration to complete and returns a <see cref="OrchestrationMetadata"/>
@@ -177,16 +222,19 @@ public abstract Task<OrchestrationMetadata> WaitForInstanceStartAsync(
177222
/// Orchestrations are long-running and could take hours, days, or months before completing.
178223
/// Orchestrations can also be eternal, in which case they'll never complete unless terminated.
179224
/// In such cases, this call may block indefinitely, so care must be taken to ensure appropriate timeouts are
180-
/// enforced using the <paramref name="cancellationToken"/> parameter.
225+
/// enforced using the <paramref name="cancellation"/> parameter.
181226
/// </para><para>
182227
/// If an orchestration instance is already complete when this method is called, the method will return immediately.
183228
/// </para>
184229
/// </remarks>
185-
/// <inheritdoc cref="WaitForInstanceStartAsync(string, CancellationToken, bool)"/>
230+
/// <inheritdoc cref="WaitForInstanceStartAsync(string, bool, CancellationToken)"/>
186231
public abstract Task<OrchestrationMetadata> WaitForInstanceCompletionAsync(
187-
string instanceId,
188-
CancellationToken cancellationToken,
189-
bool getInputsAndOutputs = false);
232+
string instanceId, bool getInputsAndOutputs = false, CancellationToken cancellation = default);
233+
234+
/// <inheritdoc cref="GetInstanceMetadataAsync(string, bool, CancellationToken)"/>
235+
public virtual Task<OrchestrationMetadata?> GetInstanceMetadataAsync(
236+
string instanceId, CancellationToken cancellation)
237+
=> this.GetInstanceMetadataAsync(instanceId, false, cancellation);
190238

191239
/// <summary>
192240
/// Fetches orchestration instance metadata from the configured durable store.
@@ -197,13 +245,9 @@ public abstract Task<OrchestrationMetadata> WaitForInstanceCompletionAsync(
197245
/// recommended that you set this parameter to <c>false</c> to minimize the network bandwidth, serialization, and
198246
/// memory costs associated with fetching the instance metadata.
199247
/// </remarks>
200-
/// <param name="instanceId">The unique ID of the orchestration instance to fetch.</param>
201-
/// <param name="getInputsAndOutputs">
202-
/// Specify <c>true</c> to fetch the orchestration instance's inputs, outputs, and custom status, or <c>false</c> to
203-
/// omit them.
204-
/// </param>
205-
/// <inheritdoc cref="WaitForInstanceStartAsync(string, CancellationToken, bool)"/>
206-
public abstract Task<OrchestrationMetadata?> GetInstanceMetadataAsync(string instanceId, bool getInputsAndOutputs);
248+
/// <inheritdoc cref="WaitForInstanceStartAsync(string, bool, CancellationToken)"/>
249+
public abstract Task<OrchestrationMetadata?> GetInstanceMetadataAsync(
250+
string instanceId, bool getInputsAndOutputs = false, CancellationToken cancellation = default);
207251

208252
/// <summary>
209253
/// Queries orchestration instances.

src/Client/Core/OrchestrationMetadata.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ namespace Microsoft.DurableTask.Client;
1111
/// </summary>
1212
/// <remarks>
1313
/// Instances of this class are produced by methods in the <see cref="DurableTaskClient"/> class, such as
14-
/// <see cref="DurableTaskClient.GetInstanceMetadataAsync"/>,
15-
/// <see cref="DurableTaskClient.WaitForInstanceStartAsync"/> and
16-
/// <see cref="DurableTaskClient.WaitForInstanceCompletionAsync"/>.
14+
/// <see cref="DurableTaskClient.GetInstanceMetadataAsync(string, CancellationToken)"/>,
15+
/// <see cref="DurableTaskClient.WaitForInstanceStartAsync(string, CancellationToken)"/> and
16+
/// <see cref="DurableTaskClient.WaitForInstanceCompletionAsync(string, CancellationToken)"/>.
1717
/// </remarks>
1818
public sealed class OrchestrationMetadata
1919
{
@@ -117,9 +117,9 @@ public OrchestrationMetadata(string name, string instanceId)
117117
/// </summary>
118118
/// <remarks>
119119
/// This method can only be used when inputs and outputs are explicitly requested from the
120-
/// <see cref="DurableTaskClient.GetInstanceMetadataAsync"/> or
121-
/// <see cref="DurableTaskClient.WaitForInstanceCompletionAsync"/> method that produced this
122-
/// <see cref="OrchestrationMetadata"/> object.
120+
/// <see cref="DurableTaskClient.GetInstanceMetadataAsync(string, CancellationToken)"/> or
121+
/// <see cref="DurableTaskClient.WaitForInstanceCompletionAsync(string, CancellationToken)"/> method that produced
122+
/// this <see cref="OrchestrationMetadata"/> object.
123123
/// </remarks>
124124
/// <typeparam name="T">The type to deserialize the orchestration input into.</typeparam>
125125
/// <returns>Returns the deserialized input value.</returns>
@@ -143,9 +143,9 @@ public OrchestrationMetadata(string name, string instanceId)
143143
/// </summary>
144144
/// <remarks>
145145
/// This method can only be used when inputs and outputs are explicitly requested from the
146-
/// <see cref="DurableTaskClient.GetInstanceMetadataAsync"/> or
147-
/// <see cref="DurableTaskClient.WaitForInstanceCompletionAsync"/> method that produced this
148-
/// <see cref="OrchestrationMetadata"/> object.
146+
/// <see cref="DurableTaskClient.GetInstanceMetadataAsync(string, CancellationToken)"/> or
147+
/// <see cref="DurableTaskClient.WaitForInstanceCompletionAsync(string, CancellationToken)"/> method that produced
148+
/// this <see cref="OrchestrationMetadata"/> object.
149149
/// </remarks>
150150
/// <typeparam name="T">The type to deserialize the orchestration output into.</typeparam>
151151
/// <returns>Returns the deserialized output value.</returns>
@@ -169,9 +169,9 @@ public OrchestrationMetadata(string name, string instanceId)
169169
/// </summary>
170170
/// <remarks>
171171
/// This method can only be used when inputs and outputs are explicitly requested from the
172-
/// <see cref="DurableTaskClient.GetInstanceMetadataAsync"/> or
173-
/// <see cref="DurableTaskClient.WaitForInstanceCompletionAsync"/> method that produced this
174-
/// <see cref="OrchestrationMetadata"/> object.
172+
/// <see cref="DurableTaskClient.GetInstanceMetadataAsync(string, CancellationToken)"/> or
173+
/// <see cref="DurableTaskClient.WaitForInstanceCompletionAsync(string, CancellationToken)"/> method that produced
174+
/// this <see cref="OrchestrationMetadata"/> object.
175175
/// </remarks>
176176
/// <typeparam name="T">The type to deserialize the orchestration' custom status into.</typeparam>
177177
/// <returns>Returns the deserialized custom status value.</returns>

0 commit comments

Comments
 (0)