From 2f99e8184970e5ec5256822be1af776b6487dadd Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Tue, 26 Nov 2024 10:38:14 -0800 Subject: [PATCH] Get bridge data bassed through --- src/Temporalio/Api/Activity/V1/Message.cs | 13 +- src/Temporalio/Bridge/Cargo.lock | 28 ++-- src/Temporalio/Bridge/Interop/Interop.cs | 10 +- .../Bridge/include/temporal-sdk-bridge.h | 129 ++++++++++-------- src/Temporalio/Bridge/src/worker.rs | 87 ++++++------ src/Temporalio/Worker/Tuning/SlotInfo.cs | 21 +++ .../Worker/Tuning/SlotMarkUsedContext.cs | 17 ++- src/Temporalio/Worker/Tuning/SlotPermit.cs | 18 +++ .../Worker/Tuning/SlotReleaseContext.cs | 17 ++- .../Worker/Tuning/SlotReserveContext.cs | 41 ++++-- .../Worker/WorkerTuningTests.cs | 2 +- 11 files changed, 236 insertions(+), 147 deletions(-) diff --git a/src/Temporalio/Api/Activity/V1/Message.cs b/src/Temporalio/Api/Activity/V1/Message.cs index 6be7cec..f591492 100644 --- a/src/Temporalio/Api/Activity/V1/Message.cs +++ b/src/Temporalio/Api/Activity/V1/Message.cs @@ -50,7 +50,6 @@ static MessageReflection() { } #region Messages - [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] public sealed partial class ActivityOptions : pb::IMessage #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE , pb::IBufferMessage @@ -396,11 +395,7 @@ public void MergeFrom(pb::CodedInputStream input) { #else uint tag; while ((tag = input.ReadTag()) != 0) { - if ((tag & 7) == 4) { - // Abort on any end group tag. - return; - } - switch(tag) { + switch(tag) { default: _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; @@ -457,11 +452,7 @@ public void MergeFrom(pb::CodedInputStream input) { void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { - if ((tag & 7) == 4) { - // Abort on any end group tag. - return; - } - switch(tag) { + switch(tag) { default: _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; diff --git a/src/Temporalio/Bridge/Cargo.lock b/src/Temporalio/Bridge/Cargo.lock index 8249ea3..708cc45 100644 --- a/src/Temporalio/Bridge/Cargo.lock +++ b/src/Temporalio/Bridge/Cargo.lock @@ -1277,9 +1277,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" @@ -1307,9 +1307,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.164" +version = "0.2.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" [[package]] name = "libredox" @@ -2189,9 +2189,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.18" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", @@ -2507,9 +2507,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.32.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ae3f4f7d64646c46c4cae4e3f01d1c5d255c7406fdd7c7f999a94e488791" +checksum = "4c33cd241af0f2e9e3b5c32163b873b29956890b5342e6745b917ce9d490f4af" dependencies = [ "core-foundation-sys", "libc", @@ -2982,9 +2982,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -2993,9 +2993,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -3004,9 +3004,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", diff --git a/src/Temporalio/Bridge/Interop/Interop.cs b/src/Temporalio/Bridge/Interop/Interop.cs index 2ee027e..b2ae62b 100644 --- a/src/Temporalio/Bridge/Interop/Interop.cs +++ b/src/Temporalio/Bridge/Interop/Interop.cs @@ -942,13 +942,13 @@ internal partial struct _Anonymous_e__Union } } - internal partial struct SlotMarkUsedCtx + internal unsafe partial struct SlotMarkUsedCtx { [NativeTypeName("struct SlotInfo")] public SlotInfo slot_info; - [NativeTypeName("bool")] - public byte slot_permit; + [NativeTypeName("const void *")] + public void* slot_permit; } internal unsafe partial struct SlotReleaseCtx @@ -956,8 +956,8 @@ internal unsafe partial struct SlotReleaseCtx [NativeTypeName("const struct SlotInfo *")] public SlotInfo* slot_info; - [NativeTypeName("bool")] - public byte slot_permit; + [NativeTypeName("const void *")] + public void* slot_permit; } internal static unsafe partial class Methods diff --git a/src/Temporalio/Bridge/include/temporal-sdk-bridge.h b/src/Temporalio/Bridge/include/temporal-sdk-bridge.h index 9fb4a6b..d572e60 100644 --- a/src/Temporalio/Bridge/include/temporal-sdk-bridge.h +++ b/src/Temporalio/Bridge/include/temporal-sdk-bridge.h @@ -383,16 +383,85 @@ typedef struct ResourceBasedSlotSupplier { struct ResourceBasedTunerOptions tuner_options; } ResourceBasedSlotSupplier; +typedef struct SlotReserveCtx { + enum SlotKindType slot_type; + struct ByteArrayRef task_queue; + struct ByteArrayRef worker_identity; + struct ByteArrayRef worker_build_id; + bool is_sticky; +} SlotReserveCtx; + +typedef void (*CustomReserveSlotCallback)(struct SlotReserveCtx ctx); + +typedef void (*CustomTryReserveSlotCallback)(struct SlotReserveCtx ctx); + +typedef enum SlotInfo_Tag { + WorkflowSlotInfo, + ActivitySlotInfo, + LocalActivitySlotInfo, +} SlotInfo_Tag; + +typedef struct WorkflowSlotInfo_Body { + struct ByteArrayRef workflow_type; + bool is_sticky; +} WorkflowSlotInfo_Body; + +typedef struct ActivitySlotInfo_Body { + struct ByteArrayRef activity_type; +} ActivitySlotInfo_Body; + +typedef struct LocalActivitySlotInfo_Body { + struct ByteArrayRef activity_type; +} LocalActivitySlotInfo_Body; + +typedef struct SlotInfo { + SlotInfo_Tag tag; + union { + WorkflowSlotInfo_Body workflow_slot_info; + ActivitySlotInfo_Body activity_slot_info; + LocalActivitySlotInfo_Body local_activity_slot_info; + }; +} SlotInfo; + +typedef struct SlotMarkUsedCtx { + struct SlotInfo slot_info; + /** + * User instance of a slot permit. + */ + const void *slot_permit; +} SlotMarkUsedCtx; + +typedef void (*CustomMarkSlotUsedCallback)(struct SlotMarkUsedCtx ctx); + +typedef struct SlotReleaseCtx { + const struct SlotInfo *slot_info; + /** + * User instance of a slot permit. + */ + const void *slot_permit; +} SlotReleaseCtx; + +typedef void (*CustomReleaseSlotCallback)(struct SlotReleaseCtx ctx); + typedef struct CustomSlotSupplier_WorkflowSlotKind { - const void *csharp_obj; + CustomReserveSlotCallback reserve; + CustomTryReserveSlotCallback try_reserve; + CustomMarkSlotUsedCallback mark_used; + CustomReleaseSlotCallback release; } CustomSlotSupplier_WorkflowSlotKind; typedef struct CustomSlotSupplier_ActivitySlotKind { - const void *csharp_obj; + CustomReserveSlotCallback reserve; + CustomTryReserveSlotCallback try_reserve; + CustomMarkSlotUsedCallback mark_used; + CustomReleaseSlotCallback release; } CustomSlotSupplier_ActivitySlotKind; typedef struct CustomSlotSupplier_LocalActivitySlotKind { - const void *csharp_obj; + CustomReserveSlotCallback reserve; + CustomTryReserveSlotCallback try_reserve; + CustomMarkSlotUsedCallback mark_used; + CustomReleaseSlotCallback release; } CustomSlotSupplier_LocalActivitySlotKind; typedef enum CustomSlotSupplierOfType_Tag { @@ -493,52 +562,6 @@ typedef struct WorkerReplayPushResult { const struct ByteArray *fail; } WorkerReplayPushResult; -typedef struct SlotReserveCtx { - enum SlotKindType slot_type; - struct ByteArrayRef task_queue; - struct ByteArrayRef worker_identity; - struct ByteArrayRef worker_build_id; - bool is_sticky; -} SlotReserveCtx; - -typedef enum SlotInfo_Tag { - WorkflowSlotInfo, - ActivitySlotInfo, - LocalActivitySlotInfo, -} SlotInfo_Tag; - -typedef struct WorkflowSlotInfo_Body { - struct ByteArrayRef workflow_type; - bool is_sticky; -} WorkflowSlotInfo_Body; - -typedef struct ActivitySlotInfo_Body { - struct ByteArrayRef activity_type; -} ActivitySlotInfo_Body; - -typedef struct LocalActivitySlotInfo_Body { - struct ByteArrayRef activity_type; -} LocalActivitySlotInfo_Body; - -typedef struct SlotInfo { - SlotInfo_Tag tag; - union { - WorkflowSlotInfo_Body workflow_slot_info; - ActivitySlotInfo_Body activity_slot_info; - LocalActivitySlotInfo_Body local_activity_slot_info; - }; -} SlotInfo; - -typedef struct SlotMarkUsedCtx { - struct SlotInfo slot_info; - bool slot_permit; -} SlotMarkUsedCtx; - -typedef struct SlotReleaseCtx { - const struct SlotInfo *slot_info; - bool slot_permit; -} SlotReleaseCtx; - #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -697,14 +720,6 @@ struct WorkerReplayPushResult worker_replay_push(struct Worker *worker, struct ByteArrayRef workflow_id, struct ByteArrayRef history); -extern void ReserveSlot(const void *csharp_obj, struct SlotReserveCtx ctx); - -extern void TryReserveSlot(const void *csharp_obj, struct SlotReserveCtx ctx); - -extern void MarkSlotUsed(const void *csharp_obj, struct SlotMarkUsedCtx ctx); - -extern void ReleaseSlot(const void *csharp_obj, struct SlotReleaseCtx ctx); - #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/src/Temporalio/Bridge/src/worker.rs b/src/Temporalio/Bridge/src/worker.rs index c837728..b372f62 100644 --- a/src/Temporalio/Bridge/src/worker.rs +++ b/src/Temporalio/Bridge/src/worker.rs @@ -65,7 +65,7 @@ pub struct TunerHolder { } #[repr(C)] -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy)] pub enum SlotSupplier { FixedSize(FixedSizeSlotSupplier), ResourceBased(ResourceBasedSlotSupplier), @@ -73,13 +73,13 @@ pub enum SlotSupplier { } #[repr(C)] -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy)] pub struct FixedSizeSlotSupplier { num_slots: usize, } #[repr(C)] -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy)] pub struct ResourceBasedSlotSupplier { minimum_slots: usize, maximum_slots: usize, @@ -96,55 +96,49 @@ pub enum CustomSlotSupplierOfType { } impl CustomSlotSupplierOfType { - // TODO: This is kinda weird + // This is kinda weird but AFAICT there's not really a nicer way to coerce the generic here. fn into_ss( self, ) -> Arc + Send + Sync + 'static> { Arc::new(match self { CustomSlotSupplierOfType::WorkflowCustomSlotSupplier(s) => CustomSlotSupplier { - csharp_obj: s.csharp_obj, + reserve: s.reserve, + try_reserve: s.try_reserve, + mark_used: s.mark_used, + release: s.release, _pd: Default::default(), }, CustomSlotSupplierOfType::ActivityCustomSlotSupplier(s) => CustomSlotSupplier { - csharp_obj: s.csharp_obj, + reserve: s.reserve, + try_reserve: s.try_reserve, + mark_used: s.mark_used, + release: s.release, _pd: Default::default(), }, CustomSlotSupplierOfType::LocalActivityCustomSlotSupplier(s) => CustomSlotSupplier { - csharp_obj: s.csharp_obj, + reserve: s.reserve, + try_reserve: s.try_reserve, + mark_used: s.mark_used, + release: s.release, _pd: Default::default(), }, }) } } -// For reasons that aren't immediately clear to me the generic parameter is also required to -// implement PartialEq, even though `PhantomData` will always implement it just fine, so we have -// this manual implementation. -impl PartialEq for CustomSlotSupplierOfType { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - ( - CustomSlotSupplierOfType::WorkflowCustomSlotSupplier(a), - CustomSlotSupplierOfType::WorkflowCustomSlotSupplier(b), - ) => a.csharp_obj == b.csharp_obj, - ( - CustomSlotSupplierOfType::ActivityCustomSlotSupplier(a), - CustomSlotSupplierOfType::ActivityCustomSlotSupplier(b), - ) => a.csharp_obj == b.csharp_obj, - ( - CustomSlotSupplierOfType::LocalActivityCustomSlotSupplier(a), - CustomSlotSupplierOfType::LocalActivityCustomSlotSupplier(b), - ) => a.csharp_obj == b.csharp_obj, - _ => false, - } - } -} +type CustomReserveSlotCallback = unsafe extern "C" fn(ctx: SlotReserveCtx); +type CustomTryReserveSlotCallback = unsafe extern "C" fn(ctx: SlotReserveCtx); +type CustomMarkSlotUsedCallback = unsafe extern "C" fn(ctx: SlotMarkUsedCtx); +type CustomReleaseSlotCallback = unsafe extern "C" fn(ctx: SlotReleaseCtx); #[repr(C)] #[derive(Clone, Copy, PartialEq)] pub struct CustomSlotSupplier { - csharp_obj: *const libc::c_void, + reserve: CustomReserveSlotCallback, + try_reserve: CustomTryReserveSlotCallback, + mark_used: CustomMarkSlotUsedCallback, + release: CustomReleaseSlotCallback, _pd: std::marker::PhantomData, } @@ -184,13 +178,15 @@ pub enum SlotInfo { #[repr(C)] pub struct SlotMarkUsedCtx { slot_info: SlotInfo, - slot_permit: bool, + /// User instance of a slot permit. + slot_permit: *const libc::c_void, } #[repr(C)] pub struct SlotReleaseCtx { slot_info: *const SlotInfo, - slot_permit: bool, + /// User instance of a slot permit. + slot_permit: *const libc::c_void, } #[async_trait::async_trait] @@ -202,7 +198,7 @@ impl temporal_sdk_core_api::worker::SlotSupplier async fn reserve_slot(&self, ctx: &dyn SlotReservationContext) -> SlotSupplierPermit { let ctx = Self::convert_reserve_ctx(ctx); unsafe { - ReserveSlot(self.csharp_obj, ctx); + (self.reserve)(ctx); } unimplemented!() } @@ -210,7 +206,7 @@ impl temporal_sdk_core_api::worker::SlotSupplier fn try_reserve_slot(&self, ctx: &dyn SlotReservationContext) -> Option { let ctx = Self::convert_reserve_ctx(ctx); unsafe { - TryReserveSlot(self.csharp_obj, ctx); + (self.try_reserve)(ctx); } unimplemented!() } @@ -218,10 +214,14 @@ impl temporal_sdk_core_api::worker::SlotSupplier fn mark_slot_used(&self, ctx: &dyn SlotMarkUsedContext) { let ctx = SlotMarkUsedCtx { slot_info: Self::convert_slot_info(ctx.info().downcast()), - slot_permit: false, + slot_permit: ctx + .permit() + .user_data::() + .map(|ud| ud.0 as *const libc::c_void) + .unwrap_or(std::ptr::null()), }; unsafe { - MarkSlotUsed(self.csharp_obj, ctx); + (self.mark_used)(ctx); } unimplemented!() } @@ -234,10 +234,14 @@ impl temporal_sdk_core_api::worker::SlotSupplier } let ctx = SlotReleaseCtx { slot_info: info_ptr, - slot_permit: false, + slot_permit: ctx + .permit() + .user_data::() + .map(|ud| ud.0 as *const libc::c_void) + .unwrap_or(std::ptr::null()), }; unsafe { - ReleaseSlot(self.csharp_obj, ctx); + (self.release)(ctx); } unimplemented!() } @@ -746,13 +750,6 @@ pub extern "C" fn worker_replay_push( } } -extern "C" { - pub fn ReserveSlot(csharp_obj: *const libc::c_void, ctx: SlotReserveCtx); - pub fn TryReserveSlot(csharp_obj: *const libc::c_void, ctx: SlotReserveCtx); - pub fn MarkSlotUsed(csharp_obj: *const libc::c_void, ctx: SlotMarkUsedCtx); - pub fn ReleaseSlot(csharp_obj: *const libc::c_void, ctx: SlotReleaseCtx); -} - impl TryFrom<&WorkerOptions> for temporal_sdk_core::WorkerConfig { type Error = anyhow::Error; diff --git a/src/Temporalio/Worker/Tuning/SlotInfo.cs b/src/Temporalio/Worker/Tuning/SlotInfo.cs index 7a0848b..c4d9c07 100644 --- a/src/Temporalio/Worker/Tuning/SlotInfo.cs +++ b/src/Temporalio/Worker/Tuning/SlotInfo.cs @@ -1,3 +1,5 @@ +using Temporalio.Bridge; + namespace Temporalio.Worker.Tuning { /// @@ -12,6 +14,25 @@ private SlotInfo() { } + /// + /// Creates a from the bridge version. + /// + /// The bridge version of the slot info. + /// The slot info. + internal static SlotInfo FromBridge(Temporalio.Bridge.Interop.SlotInfo slot_info) + { + return slot_info.tag switch + { + Temporalio.Bridge.Interop.SlotInfo_Tag.WorkflowSlotInfo => + new WorkflowSlotInfo(ByteArrayRef.ToUtf8(slot_info.workflow_slot_info.workflow_type), slot_info.workflow_slot_info.is_sticky != 0), + Temporalio.Bridge.Interop.SlotInfo_Tag.ActivitySlotInfo => + new ActivitySlotInfo(ByteArrayRef.ToUtf8(slot_info.activity_slot_info.activity_type)), + Temporalio.Bridge.Interop.SlotInfo_Tag.LocalActivitySlotInfo => + new LocalActivitySlotInfo(ByteArrayRef.ToUtf8(slot_info.local_activity_slot_info.activity_type)), + _ => throw new System.ArgumentOutOfRangeException(nameof(slot_info)), + }; + } + /// /// Info about a workflow task slot usage. /// diff --git a/src/Temporalio/Worker/Tuning/SlotMarkUsedContext.cs b/src/Temporalio/Worker/Tuning/SlotMarkUsedContext.cs index 86061b4..c69699a 100644 --- a/src/Temporalio/Worker/Tuning/SlotMarkUsedContext.cs +++ b/src/Temporalio/Worker/Tuning/SlotMarkUsedContext.cs @@ -9,12 +9,25 @@ namespace Temporalio.Worker.Tuning public class SlotMarkUsedContext { /// - /// Info about the task that will be using the slot. + /// Initializes a new instance of the class. + /// + /// The bridge version of the slot mark used context. + internal SlotMarkUsedContext(Temporalio.Bridge.Interop.SlotMarkUsedCtx ctx) + { + this.SlotInfo = SlotInfo.FromBridge(ctx.slot_info); + unsafe + { + this.Permit = SlotPermit.FromPointer(ctx.slot_permit); + } + } + + /// + /// Gets info about the task that will be using the slot. /// public SlotInfo SlotInfo { get; } /// - /// The permit that was issued when the slot was reserved. + /// Gets the permit that was issued when the slot was reserved. /// public SlotPermit Permit { get; } } diff --git a/src/Temporalio/Worker/Tuning/SlotPermit.cs b/src/Temporalio/Worker/Tuning/SlotPermit.cs index dcef96c..ef2ff1a 100644 --- a/src/Temporalio/Worker/Tuning/SlotPermit.cs +++ b/src/Temporalio/Worker/Tuning/SlotPermit.cs @@ -1,5 +1,9 @@ +using System.Runtime.InteropServices; + namespace Temporalio.Worker.Tuning { + // This class actually _is_ meant to be inherited with no members. +#pragma warning disable CA1052 /// /// A permit to use a slot for a workflow/activity/local activity task. /// You can inherit from this class to add your own data to the permit. @@ -9,5 +13,19 @@ namespace Temporalio.Worker.Tuning /// public class SlotPermit { + private SlotPermit() + { + } + + /// + /// Reconstruct a permit from a pointer. + /// + /// The pointer to the permit. + /// The permit. + internal static unsafe SlotPermit FromPointer(void* permit) + { + return (SlotPermit)GCHandle.FromIntPtr(new(permit)).Target!; + } } +#pragma warning restore CA1052 } diff --git a/src/Temporalio/Worker/Tuning/SlotReleaseContext.cs b/src/Temporalio/Worker/Tuning/SlotReleaseContext.cs index 28f642c..b731d79 100644 --- a/src/Temporalio/Worker/Tuning/SlotReleaseContext.cs +++ b/src/Temporalio/Worker/Tuning/SlotReleaseContext.cs @@ -9,12 +9,25 @@ namespace Temporalio.Worker.Tuning public class SlotReleaseContext { /// - /// Info about the task that will be using the slot. May be null if the slot was never used. + /// Initializes a new instance of the class. + /// + /// The bridge version of the slot release context. + internal SlotReleaseContext(Temporalio.Bridge.Interop.SlotReleaseCtx ctx) + { + unsafe + { + this.SlotInfo = ctx.slot_info is null ? null : SlotInfo.FromBridge(*ctx.slot_info); + this.Permit = SlotPermit.FromPointer(ctx.slot_permit); + } + } + + /// + /// Gets info about the task that will be using the slot. May be null if the slot was never used. /// public SlotInfo? SlotInfo { get; } /// - /// The permit that was issued when the slot was reserved. + /// Gets the permit that was issued when the slot was reserved. /// public SlotPermit Permit { get; } } diff --git a/src/Temporalio/Worker/Tuning/SlotReserveContext.cs b/src/Temporalio/Worker/Tuning/SlotReserveContext.cs index 5c58ebe..38f70d0 100644 --- a/src/Temporalio/Worker/Tuning/SlotReserveContext.cs +++ b/src/Temporalio/Worker/Tuning/SlotReserveContext.cs @@ -1,3 +1,5 @@ +using Temporalio.Bridge; + namespace Temporalio.Worker.Tuning { /// @@ -9,28 +11,47 @@ namespace Temporalio.Worker.Tuning public class SlotReserveContext { /// - /// Gets or sets the type of slot trying to be reserved. Always one of "workflow", "activity", or "local-activity". + /// Initializes a new instance of the class. + /// + /// The bridge version of the slot reserve context. + internal SlotReserveContext(Temporalio.Bridge.Interop.SlotReserveCtx ctx) + { + this.SlotType = ctx.slot_type switch + { + Temporalio.Bridge.Interop.SlotKindType.WorkflowSlotKindType => SlotType.Workflow, + Temporalio.Bridge.Interop.SlotKindType.ActivitySlotKindType => SlotType.Activity, + Temporalio.Bridge.Interop.SlotKindType.LocalActivitySlotKindType => SlotType.LocalActivity, + _ => throw new System.ArgumentOutOfRangeException(nameof(ctx)), + }; + this.TaskQueue = ByteArrayRef.ToUtf8(ctx.task_queue); + this.WorkerIdentity = ByteArrayRef.ToUtf8(ctx.worker_identity); + this.WorkerBuildId = ByteArrayRef.ToUtf8(ctx.worker_build_id); + this.IsSticky = ctx.is_sticky != 0; + } + + /// + /// Gets the type of slot trying to be reserved. Always one of "workflow", "activity", or "local-activity". /// - public SlotType SlotType { get; set; } + public SlotType SlotType { get; } /// - /// Gets or sets the name of the task queue for which this reservation request is associated. + /// Gets the name of the task queue for which this reservation request is associated. /// - public string TaskQueue { get; set; } + public string TaskQueue { get; } /// - /// Gets or sets the identity of the worker that is requesting the reservation. + /// Gets the identity of the worker that is requesting the reservation. /// - public string WorkerIdentity { get; set; } + public string WorkerIdentity { get; } /// - /// Gets or sets the build id of the worker that is requesting the reservation. + /// Gets the build id of the worker that is requesting the reservation. /// - public string WorkerBuildId { get; set; } + public string WorkerBuildId { get; } /// - /// Gets or sets a value indicating whether true iff this is a reservation for a sticky poll for a workflow task. + /// Gets a value indicating whether true iff this is a reservation for a sticky poll for a workflow task. /// - public bool IsSticky { get; set; } + public bool IsSticky { get; } } } diff --git a/tests/Temporalio.Tests/Worker/WorkerTuningTests.cs b/tests/Temporalio.Tests/Worker/WorkerTuningTests.cs index 1825d24..7e3f594 100644 --- a/tests/Temporalio.Tests/Worker/WorkerTuningTests.cs +++ b/tests/Temporalio.Tests/Worker/WorkerTuningTests.cs @@ -112,7 +112,7 @@ public async Task Cannot_Mix_MaxConcurrent_And_Tuner() Assert.Contains("Cannot set both Tuner and any of", argumentException.Message); } - class MySlotSupplier : ICustomSlotSupplier + private class MySlotSupplier : ICustomSlotSupplier { public Task ReserveSlotAsync(SlotReserveContext ctx) {