From f49d52c77549b599b05325d5e1379f9b38a4124d Mon Sep 17 00:00:00 2001 From: Jacob Viau Date: Wed, 19 Jul 2023 16:36:11 -0700 Subject: [PATCH] Add TaskOrchestrationContext entity abstractions --- .../TaskOrchestrationEntityFeature.cs | 97 +++++++++++++++++++ src/Abstractions/TaskOrchestrationContext.cs | 7 ++ 2 files changed, 104 insertions(+) create mode 100644 src/Abstractions/Entities/TaskOrchestrationEntityFeature.cs diff --git a/src/Abstractions/Entities/TaskOrchestrationEntityFeature.cs b/src/Abstractions/Entities/TaskOrchestrationEntityFeature.cs new file mode 100644 index 00000000..27b81125 --- /dev/null +++ b/src/Abstractions/Entities/TaskOrchestrationEntityFeature.cs @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.DurableTask.Entities; + +/// +/// Feature for interacting with durable entities from an orchestration. +/// +public abstract class TaskOrchestrationEntityFeature +{ + /// + /// Calls an operation on an entity and waits for it to complete. Does not wait for completion if + /// is set on . + /// + /// The result of the entity operation. + /// The target entity. + /// The name of the operation. + /// The operation input. + /// The call options. + /// + /// The result of the entity operation, or default() in the signal-only case. + /// + public abstract Task CallEntityAsync( + EntityInstanceId id, string operationName, object? input = null, CallEntityOptions? options = null); + + /// + /// Calls an operation on an entity and waits for it to complete. Does not wait for completion if + /// is set on . + /// + /// The result of the entity operation. + /// The target entity. + /// The name of the operation. + /// The call options. + /// + /// The result of the entity operation, or default() in the signal-only case. + /// + public virtual Task CallEntityAsync( + EntityInstanceId id, string operationName, CallEntityOptions? options) + => this.CallEntityAsync(id, operationName, null, options); + + /// + /// Calls an operation on an entity and waits for it to complete. Does not wait for completion if + /// is set on . + /// + /// The target entity. + /// The name of the operation. + /// The operation input. + /// The call options. + /// + /// A task that completes when the operation has been completed. Or in the signal-only case, a task that is either + /// already complete or completes when the operation has been enqueued. + /// + public abstract Task CallEntityAsync( + EntityInstanceId id, string operationName, object? input = null, CallEntityOptions? options = null); + + /// + /// Calls an operation on an entity and waits for it to complete. Does not wait for completion if + /// is set on . + /// + /// The target entity. + /// The name of the operation. + /// The call options. + /// + /// A task that completes when the operation has been completed. Or in the signal-only case, a task that is either + /// already complete or completes when the operation has been enqueued. + /// + public virtual Task CallEntityAsync(EntityInstanceId id, string operationName, CallEntityOptions? options) + => this.CallEntityAsync(id, operationName, null, options); + + /// + /// Acquires one or more entity locks. + /// + /// The entity IDs to lock. + /// An async-disposable which can be disposed to release the lock. + public abstract Task LockEntitiesAsync(IEnumerable entityIds); + + /// + /// Acquires one or more entity locks. + /// + /// The entity IDs to lock. + /// An async-disposable which can be disposed to release the lock. + public virtual Task LockEntitiesAsync(params EntityInstanceId[] entityIds) + => this.LockEntitiesAsync((IEnumerable)entityIds); // let the implementation decide how to handle nulls. + + /// + /// Gets a value indicating whether any entity locks are owned by this instance. + /// + /// The list of locked entities. + /// True if any locks are owned, false otherwise. + public abstract bool HasEntityLocks(out IReadOnlyList entityIds); + + /// + /// Gets a value indicating whether any entity locks are owned by this instance. + /// + /// True if any locks are owned, false otherwise. + public virtual bool HasEntityLocks() => this.HasEntityLocks(out _); +} diff --git a/src/Abstractions/TaskOrchestrationContext.cs b/src/Abstractions/TaskOrchestrationContext.cs index b3f139dc..15ba1ddc 100644 --- a/src/Abstractions/TaskOrchestrationContext.cs +++ b/src/Abstractions/TaskOrchestrationContext.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using Microsoft.DurableTask.Entities; using Microsoft.Extensions.Logging; namespace Microsoft.DurableTask; @@ -58,6 +59,12 @@ public abstract class TaskOrchestrationContext /// public abstract bool IsReplaying { get; } + /// + /// Gets the entity feature, for interacting with entities. + /// + public virtual TaskOrchestrationEntityFeature Entities => + throw new NotSupportedException($"Durable entities are not supported by {this.GetType()}."); + /// /// Gets the logger factory for this context. ///