diff --git a/src/Abstractions/OrchestrationPriorityLevel.cs b/src/Abstractions/OrchestrationPriorityLevel.cs new file mode 100644 index 00000000..80f7a0a1 --- /dev/null +++ b/src/Abstractions/OrchestrationPriorityLevel.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.DurableTask; + +/// +/// Priority level enum for intuitive priority specification. +/// +public enum OrchestrationPriorityLevel +{ + /// + /// Unspecified priority. Uses instance key (normal priority, FIFO). + /// + Unspecified = 0, + + /// + /// Highest priority (priority value 0). + /// + Urgent = 1, + + /// + /// High priority (priority value 1000). + /// + High = 2, + + /// + /// Normal priority (uses instance key, FIFO). + /// + Normal = 3, + + /// + /// Low priority (instance key + 1,000,000). + /// + Low = 4, + + /// + /// Background priority (instance key + 10,000,000). + /// + Background = 5, +} + diff --git a/src/Abstractions/TaskOptions.cs b/src/Abstractions/TaskOptions.cs index f8e527fe..7c54eacf 100644 --- a/src/Abstractions/TaskOptions.cs +++ b/src/Abstractions/TaskOptions.cs @@ -134,4 +134,14 @@ public record StartOrchestrationOptions(string? InstanceId = null, DateTimeOffse /// Gets the version to associate with the orchestration instance. /// public TaskVersion? Version { get; init; } + + /// + /// Gets the optional custom numeric priority. Lower numbers are processed more urgently. Takes precedence over PriorityLevel. + /// + public long? Priority { get; init; } + + /// + /// Gets the optional priority level for intuitive priority specification. Ignored if Priority is set. + /// + public OrchestrationPriorityLevel? PriorityLevel { get; init; } } diff --git a/src/Client/Grpc/GrpcDurableTaskClient.cs b/src/Client/Grpc/GrpcDurableTaskClient.cs index efc6d765..ef60e101 100644 --- a/src/Client/Grpc/GrpcDurableTaskClient.cs +++ b/src/Client/Grpc/GrpcDurableTaskClient.cs @@ -121,6 +121,17 @@ public override async Task ScheduleNewOrchestrationInstanceAsync( request.ScheduledStartTimestamp = Timestamp.FromDateTimeOffset(startAt.Value.ToUniversalTime()); } + // Set priority if specified (takes precedence over priorityLevel) + if (options?.Priority.HasValue == true) + { + request.Priority = options.Priority.Value; + } + // Set priorityLevel if specified and priority is not set + else if (options?.PriorityLevel.HasValue == true) + { + request.PriorityLevel = options.PriorityLevel.Value.ToGrpcPriorityLevel(); + } + using Activity? newActivity = TraceHelper.StartActivityForNewOrchestration(request); P.CreateInstanceResponse? result = await this.sidecarClient.StartInstanceAsync( diff --git a/src/Client/Grpc/ProtoUtils.cs b/src/Client/Grpc/ProtoUtils.cs index f5bc750d..11063ebd 100644 --- a/src/Client/Grpc/ProtoUtils.cs +++ b/src/Client/Grpc/ProtoUtils.cs @@ -30,4 +30,21 @@ internal static P.OrchestrationStatus ToGrpcStatus(this OrchestrationRuntimeStat _ => throw new ArgumentOutOfRangeException(nameof(status), "Unexpected value"), }; #pragma warning restore 0618 // Referencing Obsolete member. + + /// + /// Converts to . + /// + /// The priority level. + /// A . + internal static P.OrchestrationPriorityLevel ToGrpcPriorityLevel(this OrchestrationPriorityLevel priorityLevel) + => priorityLevel switch + { + OrchestrationPriorityLevel.Unspecified => P.OrchestrationPriorityLevel.Unspecified, + OrchestrationPriorityLevel.Urgent => P.OrchestrationPriorityLevel.Urgent, + OrchestrationPriorityLevel.High => P.OrchestrationPriorityLevel.High, + OrchestrationPriorityLevel.Normal => P.OrchestrationPriorityLevel.Normal, + OrchestrationPriorityLevel.Low => P.OrchestrationPriorityLevel.Low, + OrchestrationPriorityLevel.Background => P.OrchestrationPriorityLevel.Background, + _ => throw new ArgumentOutOfRangeException(nameof(priorityLevel), "Unexpected value"), + }; } diff --git a/src/Grpc/orchestrator_service.proto b/src/Grpc/orchestrator_service.proto index d59bca3c..f099ffe4 100644 --- a/src/Grpc/orchestrator_service.proto +++ b/src/Grpc/orchestrator_service.proto @@ -358,6 +358,16 @@ message OrchestratorResponse { bool requiresHistory = 7; } +// Priority level enum for intuitive priority specification +enum OrchestrationPriorityLevel { + ORCHESTRATION_PRIORITY_LEVEL_UNSPECIFIED = 0; // Uses instance key (normal priority, FIFO) + ORCHESTRATION_PRIORITY_LEVEL_URGENT = 1; // Highest priority (priority value 0) + ORCHESTRATION_PRIORITY_LEVEL_HIGH = 2; // High priority (priority value 1000) + ORCHESTRATION_PRIORITY_LEVEL_NORMAL = 3; // Normal priority (uses instance key, FIFO) + ORCHESTRATION_PRIORITY_LEVEL_LOW = 4; // Low priority (instance key + 1,000,000) + ORCHESTRATION_PRIORITY_LEVEL_BACKGROUND = 5; // Background priority (instance key + 10,000,000) +} + message CreateInstanceRequest { string instanceId = 1; string name = 2; @@ -369,6 +379,8 @@ message CreateInstanceRequest { map tags = 8; TraceContext parentTraceContext = 9; google.protobuf.Timestamp requestTime = 10; + google.protobuf.Int64Value priority = 11; // Optional custom numeric priority. Lower numbers are processed more urgently. Takes precedence over priorityLevel. + OrchestrationPriorityLevel priorityLevel = 12; // Optional priority level for intuitive priority specification. Ignored if priority is set. } message OrchestrationIdReusePolicy {