Skip to content

[ROBO-5857] .NET: IpcContext ambient context - write callback-capable contracts without a Message parameter - #127

Merged
eduard-dumitru merged 1 commit into
masterfrom
feature/ipc-context
Jul 29, 2026
Merged

[ROBO-5857] .NET: IpcContext ambient context - write callback-capable contracts without a Message parameter#127
eduard-dumitru merged 1 commit into
masterfrom
feature/ipc-context

Conversation

@eduard-dumitru

@eduard-dumitru eduard-dumitru commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Jira: ROBO-5857

image

What & why

A strongly-typed contract that wants to service callbacks is today forced to reference UiPath.Ipc, because reaching the peer requires a Message parameter on the contract method. That leaks the transport into the contract-defining assembly and makes bidirectional contracts non-agnostic.

This PR adds an ambient per-operation context, IpcContext, whose static IpcContext.Current is non-null exactly while a call is being honored. A contract implementation reaches the peer via IpcContext.Current.GetCallback<T>()no Message parameter — so the contract-defining assembly can stay free of a UiPath.Ipc reference and a bidirectional contract can be written agnostically.

Everything is additive and non-breaking: Message, CancellationToken, and the wire format are unchanged.

Changes

  • IpcContext (public sealed class) with a static IpcContext? Current backed by AsyncLocal. Exposes Client, the call's CancellationToken, and GetCallback<T>() (the same machinery behind Message.Client.GetCallback<T>()).
  • Published around the handler invocation in Server.MethodCall, so it covers inbound calls and callbacks, composes across nested calls (a callback serviced mid-call), and is null outside a call.
  • Builds net461 / net6.0 / net6.0-windows.

Tests

4 xUnit tests driven by a self-contained POCO contract with no Message parameter: Current is null outside a call and after it completes, set while honoring a call, and a Message-free contract reaches its callback purely via IpcContext.Current.GetCallback<T>().

Scope

This PR is .NET only. The Python and TypeScript work that previously rode along in this branch has been split out to #148 (ROBO-5858) — Python IpcContext, plus TypeScript AbortSignal acceptance and caller/callee cancellation propagation — so each runtime's concerns can be reviewed on their own. The two PRs are independent and can merge in either order.

🤖 Generated with Claude Code

@eduard-dumitru eduard-dumitru changed the title Add IpcContext ambient context (.NET, Python) + TS AbortSignal support .NET: IpcContext ambient context - write callback-capable contracts without a Message parameter Jul 29, 2026
Introduce `IpcContext` with a static `IpcContext? Current` backed by AsyncLocal,
published for the duration of a server-side handler (and callback) invocation in
`Server.MethodCall`. It exposes the peer (`Client`) + the call's
`CancellationToken` and a `GetCallback<T>()` that mirrors
`Message.Client.GetCallback<T>()` — so a service-contract implementation can
reach callbacks WITHOUT a `Message` parameter, letting the contract-defining
assembly stay free of a UiPath.Ipc reference.

Additive and non-breaking: `Message` injection is unchanged; `Current` is null
outside a call and composes across nested calls (a callback serviced mid-call).

Tests (xUnit, self-contained POCO contract with no `Message` param): `Current`
is null outside a call and after it completes, set while honoring a call, and a
Message-free contract reaches its callback purely via
`IpcContext.Current.GetCallback<T>()`. Builds on net461/net6.0/net6.0-windows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@eduard-dumitru eduard-dumitru changed the title .NET: IpcContext ambient context - write callback-capable contracts without a Message parameter [ROBO-5857] .NET: IpcContext ambient context - write callback-capable contracts without a Message parameter Jul 29, 2026

/// <summary>Ambient context of the IPC call being honored, letting a POCO contract reach
/// the peer without a <see cref="Message"/> parameter. Coexists with <see cref="Message"/>.</summary>
public sealed class IpcContext

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is IpcContext consumed?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


// No Message parameter anywhere: the peer is reached through the ambient context.
public Task<string> ReachCallbackViaContext()
=> IpcContext.Current!.GetCallback<IContextProbeCallback>().Pong();

@eduard-dumitru eduard-dumitru Jul 29, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mihaipetrisor82uip:
https://github.com/UiPath/coreipc/pull/127/changes#r3675063208

In the Ipc codebase itself, it's only consumed in unit tests.

@eduard-dumitru
eduard-dumitru merged commit 1f023e8 into master Jul 29, 2026
1 of 2 checks passed
@eduard-dumitru
eduard-dumitru deleted the feature/ipc-context branch July 29, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants