Skip to content

feat: add cancellation-aware RPC contracts - #10937

Merged
ReubenBond merged 16 commits into
dotnet:mainfrom
ReubenBond:rb-cancellation-aware-rpc-contracts
Sep 3, 2026
Merged

ReubenBond merged 16 commits into
dotnet:mainfrom
ReubenBond:rb-cancellation-aware-rpc-contracts

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

Orleans production RPC contracts need consistent cooperative cancellation so callers can stop queued and in-flight work without changing established wire identities or breaking existing grain implementations.

Changes

  • Adds trailing CancellationToken support across production grain, extension, and system-target contracts in Core, Runtime, Reminders, Streaming, EventSourcing, Transactions, BroadcastChannel, Dashboard, and Persistence.Memory.
  • Flows cancellation through Orleans-owned implementations, lifecycle paths, storage operations, stream registration and delivery, reminder operations, management fan-out, directory handoff, metadata, migration, and Dashboard HTTP requests.
  • Preserves rolling-upgrade compatibility by retaining legacy wire identities on token overloads. Public implementer-facing interfaces keep their existing overloads under distinct stable aliases with default forwarding.
  • Updates generated invokable alias handling so explicit Alias and Id identities can claim another overload's generated identity while retaining the full declaring-interface identity for extensions.
  • Regenerates contract manifests and public API surfaces, and adds focused compatibility, identity, and cancellation-propagation coverage.

Compatibility notes

Cancellation-control messages use non-cancelable transport tokens so the messages responsible for delivering cancellation cannot cancel themselves. Persistence, repartitioning, and cleanup paths only observe cancellation at safe boundaries, allowing side effects and protocol guards to complete consistently once committed.

Microsoft Reviewers: Open in CodeFlow

Copilot AI lite review requested due to automatic review settings September 1, 2026 05:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 High severity · 1 Medium severity

New issues introduced by this change (2)
Severity Finding
High severity src/​Orleans.CodeGenerator/​InvokableGenerator.cs — IsGeneratedMethodIdExplicitlyClaimed compares an [Id(...)] value formatted as a decimal string…
Medium severity src/​Dashboard/​Orleans.Dashboard/​Implementation/​Grains/​DashboardRemindersGrain.cs — Cancellation token is not being propagated to the reminder table operation: this uses…
What changed in this PR

This PR introduces cancellation-aware overloads across Orleans RPC contracts (grains, extensions, and system targets) while preserving existing wire identities to maintain rolling-upgrade compatibility across clusters and existing implementers.

Changes:

  • Adds CancellationToken overloads across many internal and public Orleans contracts, generally using forwarding default interface implementations to preserve legacy implementers.
  • Flows cancellation through Orleans-owned implementations (streaming, reminders, membership, directory, placement/rebalancing, transactions, dashboard) and updates OrleansContracts manifests accordingly.
  • Updates code generation/metadata to support alias/identity claiming across overloads and regenerates public API surface files, alongside new/updated compatibility tests.
File Description
test/​Transactions/​Orleans.Transactions.Tests/​TransactionCancellationCompatibilityTests.cs Adds forwarding-compat test for transactions cancellation overloads.
test/​Orleans.Streaming.Tests/​StreamingTests/​PersistentStreamCancellationCompatibilityTests.cs Adds streaming receiver/queue cancellation compatibility and cancellation-observation tests.
test/​Orleans.Streaming.Tests/​StreamingTests/​BroadcastChannels/​BroadcastChannelTests.cs Verifies publish fails fast when token is canceled.
test/​Orleans.Streaming.Tests/​StreamingTests/​BroadcastChannelCancellationCompatibilityTests.cs Adds broadcast channel cancellation overload compatibility tests.
test/​Orleans.Runtime.Tests/​StatelessWorkerActivationTests.cs Updates management calls to pass test cancellation token.
test/​Orleans.Runtime.Tests/​ManagementGrainTests.cs Updates management calls to pass test cancellation token.
test/​Orleans.Runtime.Tests/​HeterogeneousSilosTests/​UpgradeTests/​RuntimeStrategyChangeTests.cs Updates version-strategy management calls to pass cancellation token.
test/​Orleans.Runtime.Tests/​DeactivationTracingTests.cs Updates management extension calls to pass cancellation token.
test/​Orleans.Runtime.Tests/​ActivationTracingTests.cs Updates migration calls to pass cancellation token.
test/​Orleans.Runtime.Internal.Tests/​StorageTests/​PersistenceGrainTests.cs Updates provider control commands to pass cancellation token.
test/​Orleans.Runtime.Internal.Tests/​ActivationsLifeCycleTests/​ActivationCollectorTests.cs Updates activation collection calls to pass cancellation token.
test/​Orleans.Reminders.Tests/​TimerTests/​ReminderCancellationCompatibilityTests.cs Adds reminders cancellation overload forwarding + wire-identity preservation test.
test/​Orleans.Placement.Tests/​PlacementFilterTests/​SiloMetadataPlacementFilterTests.cs Updates management calls to pass cancellation token.
test/​Orleans.Placement.Tests/​PlacementFilterTests/​GrainPlacementFilterTests.cs Updates management calls to pass cancellation token.
test/​Orleans.Placement.Tests/​ActivationRepartitioningTests/​RepartitioningTestBase.cs Switches repartitioning system target calls to cancellation-aware overloads.
test/​Orleans.Placement.Tests/​ActivationRepartitioningTests/​DefaultToleranceTests.cs Updates provider control commands to pass cancellation token.
test/​Orleans.Placement.Tests/​ActivationRepartitioningTests/​CustomToleranceTests.cs Updates repartitioner diagnostics calls to pass cancellation token.
test/​Orleans.Placement.Tests/​ActivationRebalancingTests/​StaticRebalancingTests.cs Updates rebalancer/report and statistics calls to pass cancellation token.
test/​Orleans.Placement.Tests/​ActivationRebalancingTests/​StatePreservationRebalancingTests.cs Updates rebalancer/report and statistics calls to pass cancellation token.
test/​Orleans.Placement.Tests/​ActivationRebalancingTests/​DynamicRebalancingTests.cs Updates rebalancer/report and statistics calls to pass cancellation token.
test/​Orleans.Journaling.Tests/​FormatMigrationClusterTests.cs Updates management extension calls to pass cancellation token.
test/​Orleans.Journaling.Tests/​DurableGrainTests.cs Updates management extension calls to pass cancellation token.
test/​Orleans.EventSourcing.Tests/​EventSourcingTests/​ProtocolParticipantCancellationCompatibilityTests.cs Adds event-sourcing participant cancellation overload forwarding test.
test/​Orleans.DefaultCluster.Tests/​Migration/​MigrationTests.cs Updates migration calls to pass cancellation token.
test/​Orleans.DefaultCluster.Tests/​ManagementGrainTests.cs Updates management calls to pass cancellation token (including exception path).
test/​Orleans.Dashboard.Tests/​Orleans.Dashboard.UnitTests/​GrainStateTests.cs Updates dashboard grain calls to pass cancellation token.
test/​Orleans.Core.Tests/​Membership/​MembershipSystemTargetTests.cs Updates membership probe calls and expectations for cancellation-aware ping.
test/​Orleans.Core.Tests/​Manifest/​ClusterManifestProviderTests.cs Updates test system target to observe cancellation token.
test/​Extensions/​Orleans.Streaming.EventHubs.Tests/​StatisticMonitorTests/​EHStatisticMonitorTests.cs Updates provider control commands to pass cancellation token.
test/​Extensions/​Orleans.Streaming.EventHubs.Tests/​SlowConsumingTests/​EHSlowConsumingTests.cs Updates provider control commands/cleanup to pass cancellation token.
test/​Extensions/​Orleans.Reminders.Firestore.Tests/​FirestoreRemindersTests.cs Updates reminders table calls to pass cancellation token.
test/​Extensions/​Orleans.Redis.Tests/​Reminders/​RedisReminderTableTests.cs Updates reminders table calls to pass cancellation token.
test/​Extensions/​Orleans.Cosmos.Tests/​ReminderTests_Cosmos_Standalone.cs Updates reminders table calls to use cancellation-aware overloads.
test/​Extensions/​Orleans.Azure.Tests/​Streaming/​PullingAgentManagementTests.cs Updates provider control commands to pass cancellation token.
test/​Extensions/​Orleans.Azure.Tests/​Reminder/​ReminderTests_Azure_Standalone.cs Updates reminders table calls to pass cancellation token.
test/​Extensions/​Orleans.AdoNet.Tests/​Streaming/​AdoNetQueueAdapterTests.cs Updates receiver initialization to pass cancellation token.
src/​Orleans.Transactions/​State/​TransactionQueue.cs Threads cancellation token through TM/resource extension calls.
src/​Orleans.Transactions/​State/​TransactionManager.cs Adds cancellation-aware overloads and applies cancellation via WaitAsync.
src/​Orleans.Transactions/​State/​TransactionalResource.cs Adds cancellation-aware overloads and applies cancellation via WaitAsync.
src/​Orleans.Transactions/​State/​ConfirmationWorker.cs Adds cancellation token to confirm RPC call.
src/​Orleans.Transactions/​OrleansContracts.txt Updates transactions contract manifest to include cancellation overload identities.
src/​Orleans.Transactions/​DistributedTM/​TransactionManagerExtension.cs Adds cancellation-aware forwarding methods for TM extension.
src/​Orleans.Transactions/​DistributedTM/​TransactionalResourceExtension.cs Adds cancellation-aware forwarding methods for resource extension.
src/​Orleans.Transactions/​Abstractions/​ITransactionManager.cs Adds default cancellation-aware overloads for implementer compatibility.
src/​Orleans.Transactions/​Abstractions/​ITransactionalResource.cs Adds default cancellation-aware overloads for implementer compatibility.
src/​Orleans.Streaming/​QueueAdapters/​IQueueAdapterReceiver.cs Adds cancellation-aware default overloads for adapter receivers.
src/​Orleans.Streaming/​PubSub/​IPubSubRendezvousGrain.cs Adds cancellation-aware methods with explicit aliases to preserve identities.
src/​Orleans.Streaming/​PubSub/​ImplicitStreamPubSub.cs Adds cancellation-aware overloads and cancellation checks.
src/​Orleans.Streaming/​PubSub/​GrainBasedPubSubRuntime.cs Propagates cancellation token through pub-sub grain calls.
src/​Orleans.Streaming/​Providers/​SiloStreamProviderRuntime.cs Adds cancellation token to pulling-agent initialization and propagation.
src/​Orleans.Streaming/​PersistentStreams/​PersistentStreamProvider.cs Propagates cancellation token through lifecycle start/stop and agent calls.
src/​Orleans.Streaming/​PersistentStreams/​IPersistentStreamPullingAgent.cs Adds cancellation-aware aliases for pulling agent/manager system targets.
src/​Orleans.Streaming/​MemoryStreams/​MemoryStreamQueueGrain.cs Adds cancellation-aware overloads and cancellation checks.
src/​Orleans.Streaming/​MemoryStreams/​MemoryAdapterReceiver.cs Adds cancellation-aware overloads and cancellation propagation/monitoring.
src/​Orleans.Streaming/​MemoryStreams/​IMemoryStreamQueueGrain.cs Adds cancellation overloads with preserved aliases for compatibility.
src/​Orleans.Streaming/​Internal/​StreamConsumerExtension.cs Adds cancellation-aware delivery APIs and throws on cancellation.
src/​Orleans.Streaming/​Internal/​IStreamGrainExtensions.cs Adds cancellation-aware extension RPC methods with explicit aliases.
src/​Orleans.Streaming/​Generator/​GeneratorAdapterFactory.cs Adds cancellation-aware receiver methods and uses token in delay.
src/​Orleans.Runtime/​Versions/​GrainVersionStore.cs Adds cancellation-aware overloads and propagates cancellation to store grain.
src/​Orleans.Runtime/​Timers/​GrainTimer.cs Updates timer invoker RPC shape to accept cancellation token.
src/​Orleans.Runtime/​Placement/​Repartitioning/​ActivationRepartitioner.MessageSink.cs Adds cancellation-aware flush and cancellation checks.
src/​Orleans.Runtime/​Placement/​Rebalancing/​ActivationRebalancerWorker.cs Adds cancellation-aware RPC methods and propagates token to monitors.
src/​Orleans.Runtime/​Placement/​Rebalancing/​ActivationRebalancerMonitor.cs Adds cancellation-aware report RPC method.
src/​Orleans.Runtime/​Placement/​DeploymentLoadPublisher.cs Adds cancellation propagation to system target calls and periodic refresh.
src/​Orleans.Runtime/​Messaging/​Gateway.cs Propagates cancellation token to client observer call.
src/​Orleans.Runtime/​MembershipService/​SiloMetadata/​SiloMetadataSystemTarget.cs Adds cancellation-aware metadata retrieval.
src/​Orleans.Runtime/​MembershipService/​SiloMetadata/​SiloMetadataClient.cs Adds cancellation-aware metadata client API.
src/​Orleans.Runtime/​MembershipService/​SiloMetadata/​SiloMetadaCache.cs Propagates cancellation token and adds OCE handling.
src/​Orleans.Runtime/​MembershipService/​SiloMetadata/​ISiloMetadataSystemTarget.cs Updates system target contract for cancellation token.
src/​Orleans.Runtime/​MembershipService/​SiloMetadata/​ISiloMetadataClient.cs Updates client contract for cancellation token.
src/​Orleans.Runtime/​MembershipService/​MembershipSystemTarget.cs Adds cancellation-aware membership RPC contracts and propagation.
src/​Orleans.Runtime/​Manifest/​ClusterManifestProvider.cs Propagates cancellation token to silo manifest calls.
src/​Orleans.Runtime/​GrainTypeManager/​ISiloManifestSystemTarget.cs Adds cancellation-aware system target alias.
src/​Orleans.Runtime/​GrainTypeManager/​ClusterManifestSystemTarget.cs Adds cancellation checks to manifest APIs and overloads.
src/​Orleans.Runtime/​GrainDirectory/​RemoteGrainDirectory.cs Adds cancellation-aware bulk register/lookup/handoff APIs.
src/​Orleans.Runtime/​GrainDirectory/​IRemoteGrainDirectory.cs Adds cancellation-aware system target contracts with aliases.
src/​Orleans.Runtime/​GrainDirectory/​IRemoteClientDirectory.cs Adds cancellation-aware routing APIs with aliases.
src/​Orleans.Runtime/​GrainDirectory/​IGrainDirectoryPartition.cs Adds cancellation-aware test hook system target methods.
src/​Orleans.Runtime/​GrainDirectory/​GrainDirectoryPartition.cs Propagates cancellation through test hooks and async enumeration.
src/​Orleans.Runtime/​GrainDirectory/​GrainDirectoryHandoffManager.cs Updates handoff/culling calls to new cancellation-aware contracts.
src/​Orleans.Runtime/​GrainDirectory/​ClientDirectory.cs Propagates cancellation through remote client directory calls.
src/​Orleans.Runtime/​Development/​InMemoryLeaseProvider.cs Adds cancellation-aware reset contract and implementation.
src/​Orleans.Runtime/​Core/​SystemTarget.cs Adds cancellation-aware cancellation-extension system target method.
src/​Orleans.Runtime/​Catalog/​ICatalog.cs Adds cancellation-aware DeleteActivations contract alias.
src/​Orleans.Runtime/​Catalog/​Catalog.cs Adds cancellation token propagation through parallel deactivation loop.
src/​Orleans.Runtime/​Catalog/​ActivationMigrationManager.cs Adds cancellation-aware migration acceptance and propagation.
src/​Orleans.Runtime/​Catalog/​ActivationData.cs Adds cancellation-aware management extension + cancellation extension methods.
src/​Orleans.Runtime/​Cancellation/​GrainCallCancellationManager.cs Adds cancellation-aware batching contract while using non-cancelable transport tokens for actual cancellation sends.
src/​Orleans.Runtime/​Cancellation/​CancellationSourcesExtension.cs Adds cancellation-aware remote token cancel method.
src/​Orleans.Reminders/​Timers/​IReminderRegistry.cs Adds default cancellation-aware overloads for reminder registry API.
src/​Orleans.Reminders/​Timers/​IRemindable.cs Adds cancellation overload with preserved alias identity.
src/​Orleans.Reminders/​ReminderService/​ReminderRegistry.cs Propagates cancellation token through reminder grain service calls.
src/​Orleans.Reminders/​ReminderService/​InMemoryReminderTable.cs Adds cancellation-aware wrappers and cancellation propagation.
src/​Orleans.Reminders/​ReminderService/​GrainBasedReminderTable.cs Makes reminder table grain methods cancellation-aware.
src/​Orleans.Reminders/​OrleansContracts.txt Updates reminders contract manifest for cancellation overload identities.
src/​Orleans.Reminders.TestKit/​ReminderTableTestRunner.cs Updates doc reference formatting for TestOnlyClearTable.
src/​Orleans.Reminders.TestKit/​ReminderTableIntrospection.cs Updates doc references to explicit method signatures.
src/​Orleans.Persistence.Memory/​Storage/​MemoryStorageGrain.cs Adds cancellation-aware storage grain APIs.
src/​Orleans.EventSourcing/​OrleansContracts.txt Updates event-sourcing contract manifest for cancellation overload identities.
src/​Orleans.EventSourcing/​LogConsistency/​LogConsistentGrain.cs Propagates cancellation token through participant lifecycle calls.
src/​Orleans.EventSourcing/​LogConsistency/​IProtocolParticipant.cs Adds cancellation-aware overloads with preserved aliases.
src/​Orleans.EventSourcing/​LogConsistency/​ILogViewAdaptor.cs Introduces cancellation-aware adaptor hook interface.
src/​Orleans.EventSourcing/​LogConsistency/​ILogConsistencyProtocolGateway.cs Adds cancellation-aware gateway contract alias.
src/​Orleans.EventSourcing/​JournaledGrain.cs Implements cancellation-aware participant overloads and adaptor cancellation bridging.
src/​Orleans.EventSourcing/​Common/​PrimaryBasedLogViewAdaptor.cs Implements cancellation-aware post-deactivate behavior.
src/​Orleans.Core/​SystemTargetInterfaces/​ISiloControl.cs Adds cancellation-aware system target contracts with aliases.
src/​Orleans.Core/​SystemTargetInterfaces/​IMembershipService.cs Adds cancellation-aware membership system target contracts with aliases.
src/​Orleans.Core/​SystemTargetInterfaces/​IDeploymentLoadPublisher.cs Adds cancellation-aware deployment load publisher contract alias.
src/​Orleans.Core/​Runtime/​InvokableObjectManager.cs Adds cancellation-aware cancellation-extension implementation.
src/​Orleans.Core/​Runtime/​GrainCancellationTokenRuntime.cs Ensures remote token cancellation uses non-cancelable token.
src/​Orleans.Core/​Runtime/​AsyncEnumerableGrainExtension.cs Adds cancellation-aware dispose overload.
src/​Orleans.Core/​Providers/​IMemoryStorageGrain.cs Adds cancellation-aware storage grain overloads with preserved aliases.
src/​Orleans.Core/​Placement/​Repartitioning/​IActivationRepartitionerSystemTarget.cs Adds cancellation-aware system target contracts with aliases.
src/​Orleans.Core/​Placement/​Rebalancing/​IActivationRebalancerWorker.cs Adds cancellation-aware worker contract while preserving alias identity.
src/​Orleans.Core/​Placement/​Rebalancing/​IActivationRebalancerMonitor.cs Adds cancellation-aware monitor reporting contract.
src/​Orleans.Core/​Placement/​Rebalancing/​IActivationRebalancer.cs Updates API doc reference to new signature.
src/​Orleans.Core/​Manifest/​IClusterManifestSystemTarget.cs Adds cancellation-aware manifest system target aliases.
src/​Orleans.Core/​Manifest/​ClientClusterManifestProvider.cs Propagates cancellation to manifest provider calls.
src/​Orleans.Core/​ClientObservers/​ClientGatewayObserver.cs Adds cancellation-aware observer contract and implementation.
src/​Orleans.Core/​Cancellation/​IGrainCallCancellationExtension.cs Adds cancellation-aware cancel-request contract and uses non-cancelable token at call sites.
src/​Orleans.Core.Abstractions/​Versions/​IVersionStore.cs Adds cancellation-aware overloads with preserved aliases.
src/​Orleans.Core.Abstractions/​SystemTargetInterfaces/​IVersionManager.cs Adds cancellation-aware overloads with preserved aliases.
src/​Orleans.Core.Abstractions/​Runtime/​AsyncEnumerableRequest.cs Adds cancellation-aware dispose overload and updates call site to use it.
src/​Orleans.Core.Abstractions/​OrleansContracts.txt Updates core abstractions contract manifest for cancellation overload identities.
src/​Orleans.Core.Abstractions/​Core/​Internal/​IGrainManagementExtension.cs Adds cancellation-aware overloads with preserved aliases.
src/​Orleans.Core.Abstractions/​Cancellation/​ICancellationSourcesExtension.cs Adds cancellation-aware cancel-remote-token contract alias.
src/​Orleans.CodeGenerator/​MetadataGenerator.cs Skips generating method-id aliases when already explicitly claimed.
src/​Orleans.CodeGenerator/​InvokableGenerator.cs Adjusts alias emission rules based on whether generated id is explicitly claimed.
src/​Orleans.BroadcastChannel/​OrleansContracts.txt Updates broadcast channel contract manifest for cancellation overload identities.
src/​Orleans.BroadcastChannel/​BroadcastChannelWriter.cs Adds cancellation-aware publish APIs and propagation to subscribers.
src/​Orleans.BroadcastChannel/​BroadcastChannelSubscription.cs Adds cancellation-aware attach overloads (defaulting to CancellationToken.None).
src/​Dashboard/​Orleans.Dashboard/​Metrics/​GrainProfiler.cs Threads cancellation through lifecycle start/stop handlers.
src/​Dashboard/​Orleans.Dashboard/​Implementation/​SiloGrainService.cs Adds cancellation-aware silo grain service APIs.
src/​Dashboard/​Orleans.Dashboard/​Implementation/​Grains/​SiloGrainProxy.cs Adds cancellation-aware proxy APIs and metadata retrieval.
src/​Dashboard/​Orleans.Dashboard/​Implementation/​Grains/​DashboardRemindersGrain.cs Adds cancellation-aware reminders query API.
src/​Dashboard/​Orleans.Dashboard/​DashboardHost.cs Propagates cancellation through startup activation calls.
src/​Dashboard/​Orleans.Dashboard/​Core/​ISiloGrainService.cs Updates silo grain service contract methods with cancellation tokens.
src/​Dashboard/​Orleans.Dashboard/​Core/​ISiloGrainProxy.cs Updates proxy contract for metadata retrieval with cancellation tokens.
src/​Dashboard/​Orleans.Dashboard/​Core/​IDashboardRemindersGrain.cs Adds cancellation token to reminders grain contract.
src/​Dashboard/​Orleans.Dashboard/​Core/​IDashboardGrain.cs Adds cancellation tokens across dashboard grain contract surface.
src/​Dashboard/​Orleans.Dashboard/​Core/​IDashboardClient.cs Adds cancellation tokens across dashboard client contract surface.
src/​api/​Orleans.Runtime/​Orleans.Runtime.cs Regenerates public API surface to reflect cancellation-aware storage methods.
src/​api/​Orleans.Persistence.Memory/​Orleans.Persistence.Memory.cs Regenerates public API surface for cancellation-aware memory storage methods.
src/​api/​Orleans.BroadcastChannel/​Orleans.BroadcastChannel.cs Regenerates public API surface for cancellation-aware broadcast channel APIs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Orleans.CodeGenerator/InvokableGenerator.cs Outdated
Comment thread src/Dashboard/Orleans.Dashboard/Implementation/Grains/DashboardRemindersGrain.cs Outdated
@ReubenBond

Copy link
Copy Markdown
Member Author

CI shows repeated reminder-operation cancellation failures across independent matrices: Rem_Grain_StorageRecoveryAtExactDueTime_DeliversDueOccurrence fails on macOS and Windows, and Rem_Sql_1J_MultiGrainMultiReminders times out during reminder topology reconciliation. Since this PR changes cancellation-aware RPC contracts and reminder-table cancellation propagation, these failures may be related and should be investigated with the unresolved cancellation review feedback. The lease-balancer failure in the Azure Storage jobs appears unrelated and is being tracked separately. Run: https://github.com/dotnet/orleans/actions/runs/33472566290

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Review tier: Lite
Findings: None

Issues resolved since last review (2)
Severity Finding
Medium severity src/​Dashboard/​Orleans.Dashboard/​Implementation/​Grains/​DashboardRemindersGrain.cs — Cancellation token is not being propagated to the reminder table operation: this uses… View resolved comment
High severity src/​Orleans.CodeGenerator/​InvokableGenerator.cs — IsGeneratedMethodIdExplicitlyClaimed compares an [Id(...)] value formatted as a decimal string… View resolved comment
Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/Orleans.Streaming/QueueAdapters/IQueueAdapterReceiver.cs:25

  • The cancellation-aware Initialize overload ignores the provided CancellationToken. If the token is already canceled, this overload will still invoke the legacy Initialize(timeout), defeating cooperative cancellation for legacy implementations.
    src/Orleans.Streaming/QueueAdapters/IQueueAdapterReceiver.cs:82
  • The cancellation-aware Shutdown overload ignores the provided CancellationToken. If the token is already canceled, this overload will still invoke the legacy Shutdown(timeout), which can slow down shutdown and conflicts with the cancellation-aware API surface.
    src/Dashboard/Orleans.Dashboard/Metrics/GrainProfiler.cs:50
  • OnStop disposes _timer unconditionally, but _timer is initialized to null! and OnStart can throw before assigning it (cancellationToken.ThrowIfCancellationRequested). If startup is canceled before OnStart completes, StopProfiler can throw NullReferenceException during shutdown. Guard the dispose so shutdown is safe even when start was canceled.
    private Task OnStop(CancellationToken cancellationToken)
    {
        _timer.Dispose();
        cancellationToken.ThrowIfCancellationRequested();
        return Task.CompletedTask;

Copilot AI review requested due to automatic review settings September 1, 2026 10:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 2 High severity

New issues introduced by this change (2)
Severity Finding
High severity src/​Orleans.Transactions/​State/​TransactionalResource.cs — CommitReadOnly(..., CancellationToken) can throw OperationCanceledException while awaiting…
High severity src/​Orleans.Transactions/​State/​TransactionManager.cs — PrepareAndCommit(..., CancellationToken) uses .WaitAsync(cancellationToken) while awaiting…
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Dashboard/Orleans.Dashboard/Metrics/GrainProfiler.cs:50

  • OnStop disposes the timer and then throws if cancellation is requested. Throwing during shutdown after cleanup can cause lifecycle stop to fail even though the component has already been disposed; it’s also inconsistent with cooperative cancellation (stop should be best-effort cleanup). Consider removing the post-dispose ThrowIfCancellationRequested() and always completing the stop path.
    private Task OnStop(CancellationToken cancellationToken)
    {
        _timer.Dispose();
        cancellationToken.ThrowIfCancellationRequested();
        return Task.CompletedTask;

Comment thread src/Orleans.Transactions/State/TransactionalResource.cs Outdated
Comment thread src/Orleans.Transactions/State/TransactionManager.cs Outdated
Copilot AI review requested due to automatic review settings September 1, 2026 10:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Review tier: Lite
Findings: 2 High severity

Pre-existing issues (2)
Severity Finding
High severity src/​Orleans.Transactions/​State/​TransactionManager.cs — PrepareAndCommit(..., CancellationToken) uses .WaitAsync(cancellationToken) while awaiting… View comment
High severity src/​Orleans.Transactions/​State/​TransactionalResource.cs — CommitReadOnly(..., CancellationToken) can throw OperationCanceledException while awaiting… View comment
Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/Orleans.BroadcastChannel/BroadcastChannelWriter.cs:124

  • PublishToSubscriber will log OperationCanceledException as an error. When Publish is canceled, this will produce noisy error logs even though cancellation is expected. Handle OperationCanceledException (when the provided token is canceled) separately and avoid error logging; optionally swallow it for fire-and-forget delivery.
            catch (Exception ex)
            {
                LogErrorExceptionWhenSendingItem(_logger, ex, consumer.GetGrainId());
                if (!_fireAndForgetDelivery)
                {

src/Orleans.Runtime/Placement/Repartitioning/ActivationRepartitioner.MessageSink.cs:140

  • FlushBuffers accepts a CancellationToken but the delay inside the loop does not pass it, so cancellation may not be observed until after the delay completes. Pass the token to Task.Delay so cancellation can interrupt the wait promptly.
    src/Orleans.Streaming/MemoryStreams/MemoryAdapterReceiver.cs:95
  • Shutdown has a dedicated cancellation catch which records TrackShutdown(false,...), but the early ThrowIfCancellationRequested() occurs before the try/catch, so a pre-canceled token will bypass the telemetry and throw without being tracked. Move the cancellation check inside the try block (after starting the stopwatch) so cancellation is consistently observed and reported.

Copilot AI review requested due to automatic review settings September 1, 2026 11:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Review tier: Lite
Findings: None

Issues resolved since last review (2)
Severity Finding
High severity src/​Orleans.Transactions/​State/​TransactionManager.cs — PrepareAndCommit(..., CancellationToken) uses .WaitAsync(cancellationToken) while awaiting… View resolved comment
High severity src/​Orleans.Transactions/​State/​TransactionalResource.cs — CommitReadOnly(..., CancellationToken) can throw OperationCanceledException while awaiting… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Dashboard/Orleans.Dashboard/Metrics/GrainProfiler.cs:50

  • OnStop disposes the timer and then calls cancellationToken.ThrowIfCancellationRequested(). During silo shutdown, the lifecycle cancellation token is commonly signaled, so this can throw after cleanup has already occurred and potentially fault the shutdown path. Cleanup methods should generally be best-effort and not throw due to cancellation after performing disposal.
    private Task OnStop(CancellationToken cancellationToken)
    {
        _timer.Dispose();
        cancellationToken.ThrowIfCancellationRequested();
        return Task.CompletedTask;

Copilot AI review requested due to automatic review settings September 2, 2026 10:36
@ReubenBond
ReubenBond force-pushed the rb-cancellation-aware-rpc-contracts branch from b07d8fb to edc751b Compare September 2, 2026 10:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

A few newly cancellation-aware paths still don’t fully propagate or promptly observe the provided cancellation token (eg, MemoryAdapterReceiver dequeue and FlushBuffers delay), which undermines the PR’s core cancellation guarantee.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity · 1 Low severity

New issues introduced by this change (2)
Severity Finding
Medium severity src/​Orleans.Streaming/​MemoryStreams/​MemoryAdapterReceiver.cs — GetQueueMessagesAsync(..., CancellationToken) ignores the provided cancellation token for the…
Low severity src/​Dashboard/​Orleans.Dashboard/​Implementation/​Grains/​DashboardRemindersGrain.cs — ReadRows(..., cancellationToken) already accepts and can observe the request token, so the extra…
Suppressed comments (1)

src/Orleans.Runtime/Placement/Repartitioning/ActivationRepartitioner.MessageSink.cs:141

  • FlushBuffers checks cancellationToken but the Task.Delay inside the loop is not cancellable, which can unnecessarily delay cancellation for up to the delay interval (and repeats if the queue stays non-empty). Use the token with Task.Delay so cancellation is observed promptly.

Comment thread src/Orleans.Streaming/MemoryStreams/MemoryAdapterReceiver.cs
Copilot AI review requested due to automatic review settings September 2, 2026 12:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

ActivationRepartitionerSystemTarget.FlushBuffers does not actually observe the provided CancellationToken inside its delay loop, so cancellation can’t interrupt long-running flushes.

Review tier: Lite
Findings: None

Issues resolved since last review (2)
Severity Finding
Low severity src/​Dashboard/​Orleans.Dashboard/​Implementation/​Grains/​DashboardRemindersGrain.cs — ReadRows(..., cancellationToken) already accepts and can observe the request token, so the extra… View resolved comment
Medium severity src/​Orleans.Streaming/​MemoryStreams/​MemoryAdapterReceiver.cs — GetQueueMessagesAsync(..., CancellationToken) ignores the provided cancellation token for the… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Orleans.Runtime/Placement/Repartitioning/ActivationRepartitioner.MessageSink.cs:141

  • FlushBuffers accepts a CancellationToken but the loop does not observe it: Task.Delay is called without the token, so cancellation won't interrupt a long-running flush and callers can hang until the buffer drains.

Copilot AI review requested due to automatic review settings September 2, 2026 22:05
@ReubenBond
ReubenBond force-pushed the rb-cancellation-aware-rpc-contracts branch from dcba912 to ad04dc1 Compare September 2, 2026 22:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Two cancellation-aware implementations still ignore or mishandle cancellation (non-cancelable delay loop in FlushBuffers and cancellation swallowed/logged as a fallback path in ClientClusterManifestProvider).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity src/​Orleans.Core/​Manifest/​ClientClusterManifestProvider.cs — GetClusterManifestUpdate catches all exceptions, including OperationCanceledException from the…
Suppressed comments (1)

src/Orleans.Runtime/Placement/Repartitioning/ActivationRepartitioner.MessageSink.cs:141

  • FlushBuffers(CancellationToken) only checks cancellation once and then awaits Task.Delay(...) without passing the token, so a canceled token will not actually interrupt the loop and tests/ops can hang until buffers drain.

Comment thread src/Orleans.Core/Manifest/ClientClusterManifestProvider.cs
@github-actions

github-actions Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage

Metric Pull request Current main Variance
Lines 81.30% (105,576 / 129,861) 81.45% (105,052 / 128,975) -0.1522 pp
Branches 70.18% (30,007 / 42,758) 70.12% (29,839 / 42,552) +0.0551 pp

Report-only conclusion: mixed.

The current-main baseline is commit 84352a718c and uses the same reviewed coverage matrix.

Coverage combines every CI test matrix job, including providers, CodeGen, .NET 8/10, Linux, Windows, and macOS, using canonical physical source and branch identities.

The comparison remains report-only while normal line and branch variance is calibrated.

Coverage details

Copilot AI review requested due to automatic review settings September 2, 2026 23:55
Copilot AI review requested due to automatic review settings September 3, 2026 06:10
@ReubenBond
ReubenBond force-pushed the rb-cancellation-aware-rpc-contracts branch from 89069a0 to 5907263 Compare September 3, 2026 06:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

GrainProfiler lifecycle start/stop cancellation handling can throw and/or leave _timer uninitialized, risking shutdown/startup failures (including potential NullReferenceException).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity · 2 Low severity

New issues introduced by this change (1)
Severity Finding
Medium severity src/​Dashboard/​Orleans.Dashboard/​Metrics/​GrainProfiler.cs — OnStart throws on a canceled lifecycle token before initializing _timer. Since _timer is…
Pre-existing issues (2)
Severity Finding
Low severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryRollingUpgradeTests.cs — Redundant cancellation: GetDetailedGrainReport(grainId, cancellationToken) already observes the… View comment
Low severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryLeaseTests.cs — Redundant cancellation: KillSiloAsync already receives cancellationToken, so the additional… View comment
Suppressed comments (1)

src/Dashboard/Orleans.Dashboard/Metrics/GrainProfiler.cs:50

  • OnStop disposes the timer and then calls ThrowIfCancellationRequested(). Throwing during lifecycle stop can turn normal shutdown cancellation into an error path and can also leave disposal as the only side effect before throwing. Since the timer is the main resource here, dispose it and return a completed task without throwing.
    private Task OnStop(CancellationToken cancellationToken)
    {
        _timer.Dispose();
        cancellationToken.ThrowIfCancellationRequested();
        return Task.CompletedTask;
    }

Comment thread src/Dashboard/Orleans.Dashboard/Metrics/GrainProfiler.cs
Copilot AI review requested due to automatic review settings September 3, 2026 07:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

A timeout-linked cancellation token is currently not propagated into an updated cancellation-aware RPC call in GrainDirectoryRollingUpgradeTests, leaving the underlying request uncancelable by the intended timeout.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryRollingUpgradeTests.cs — The timeout-linked token source (cancellation) is only applied via WaitAsync, while the…
Issues resolved since last review (3)
Severity Finding
Medium severity src/​Dashboard/​Orleans.Dashboard/​Metrics/​GrainProfiler.cs — OnStart throws on a canceled lifecycle token before initializing _timer. Since _timer is… View resolved comment
Low severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryRollingUpgradeTests.cs — Redundant cancellation: GetDetailedGrainReport(grainId, cancellationToken) already observes the… View resolved comment
Low severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryLeaseTests.cs — Redundant cancellation: KillSiloAsync already receives cancellationToken, so the additional… View resolved comment

Copilot AI review requested due to automatic review settings September 3, 2026 09:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Some updated grain-directory tests still don’t propagate the timeout-linked cancellation token to the underlying RPC (and one adds a redundant WaitAsync wrapper), which undermines the intended cancellation-aware behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity · 1 Low severity

New issues introduced by this change (2)
Severity Finding
Medium severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryRollingUpgradeTests.cs — The per-partition membership wait uses timeout.Token for WaitAsync, but passes the outer…
Low severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryResilienceTests.cs — CheckIntegrityAsync now accepts cancellationToken, so the extra .WaitAsync(cancellationToken)…
Issues resolved since last review (1)
Severity Finding
Medium severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryRollingUpgradeTests.cs — The timeout-linked token source (cancellation) is only applied via WaitAsync, while the… View resolved comment

Comment thread test/Orleans.GrainDirectory.Tests/GrainDirectory/GrainDirectoryResilienceTests.cs Outdated
Copilot AI review requested due to automatic review settings September 3, 2026 13:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

A few newly added cancellation-aware default interface overloads accept a CancellationToken but currently do not observe it, which undermines the cooperative-cancellation contract being introduced.

Review tier: Lite
Findings: None

Issues resolved since last review (2)
Severity Finding
Low severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryResilienceTests.cs — CheckIntegrityAsync now accepts cancellationToken, so the extra .WaitAsync(cancellationToken)… View resolved comment
Medium severity test/​Orleans.GrainDirectory.Tests/​GrainDirectory/​GrainDirectoryRollingUpgradeTests.cs — The per-partition membership wait uses timeout.Token for WaitAsync, but passes the outer… View resolved comment
Suppressed comments (3)

Previously missed (2) — in code that hasn't changed since the last review.

src/Orleans.Reminders/Timers/IRemindable.cs:31

  • The new ReceiveReminder overload ignores its CancellationToken, so the runtime can invoke it with a canceled token and the legacy callback will still execute. Add an early ThrowIfCancellationRequested() before forwarding to preserve expected cooperative-cancellation semantics without breaking existing implementations.
    src/Orleans.Streaming/QueueAdapters/IQueueAdapterReceiver.cs:25
  • The cancellation-aware overload ignores the provided CancellationToken, so callers can pass a canceled token and the legacy Initialize(timeout) will still run. To make this overload cancellation-aware (at least for pre-canceled tokens) add an early ThrowIfCancellationRequested() before delegating to the legacy method.

This issue also appears on line 82 of the same file.

src/Orleans.Streaming/QueueAdapters/IQueueAdapterReceiver.cs:82

  • The cancellation-aware Shutdown overload currently ignores the provided CancellationToken, so cancellation has no effect for legacy implementations. Add an early ThrowIfCancellationRequested() before delegating to the legacy Shutdown(timeout) method so callers can cooperatively cancel before shutdown starts.

@ReubenBond
ReubenBond merged commit 325e7d6 into dotnet:main Sep 3, 2026
77 checks passed
@ReubenBond
ReubenBond deleted the rb-cancellation-aware-rpc-contracts branch September 3, 2026 14:00
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants