Skip to content

fix(actors): subscribe one local cache invalidator PID per cluster member - #174

Merged
sfmskywalker merged 6 commits into
elsa-workflows:mainfrom
DenDeline:bugfix/173-local-cache-invalidator-pid
Sep 6, 2026
Merged

fix(actors): subscribe one local cache invalidator PID per cluster member#174
sfmskywalker merged 6 commits into
elsa-workflows:mainfrom
DenDeline:bugfix/173-local-cache-invalidator-pid

Conversation

@DenDeline

@DenDeline DenDeline commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace the placement-managed LocalCache virtual grain with one named, member-local cache invalidator actor per Proto.Actor cluster member. Each actor subscribes with its concrete PID; host startup awaits the acknowledgement, and shutdown unsubscribes before stopping the actor.

Fixes #173.

Changes

  • spawn one local system actor named $memory-cache-invalidator per actor system
  • subscribe and unsubscribe its concrete PID through the hosted-service lifecycle
  • stop the actor when subscription fails and always stop it when unsubscription fails or is cancelled
  • remove the obsolete LocalCache grain contract, generated API, cluster kind, helper, and grain-codegen dependency
  • retain LocalCache.Messages.proto and LocalCacheMessagesReflection.Descriptor for Pub/Sub serialization
  • add focused multi-member integration coverage

Breaking change and upgrade limitation

The generated public LocalCache grain APIs and BackgroundService base type are intentionally removed. Consumers using them must update and recompile. Mixed-version rolling upgrades are unsupported: stop every old member first, and clear durable change-token-signals subscriber state containing legacy cluster identities before starting the new version.

Validation

  • distributed ProtoActor integration tests: 8/8 passed, followed by three consecutive 8/8 no-build runs
  • actor unit tests: 6/6 passed
  • distributed ProtoActor module build: net8.0, net9.0, and net10.0 succeeded with 0 errors
  • git diff --check origin/main...HEAD: passed

The tests cover acknowledgement-gated startup, one PID per member, exact per-member delivery, graceful removal, post-stop delivery, descriptor/kind registration, subscription failure cleanup, and unsubscription failure cleanup.

Review

Maintainer review is being performed directly on the current head. Copilot is intentionally bypassed per maintainer direction. Greptile is unavailable because its author allowlist rejects this contributor PR.

Register StartClusterMember with priority -100 and add regression coverage for hosted-service ordering.

Fixes elsa-workflows#167
Reuse the RemoteConfig attached to the ActorSystem when registering virtual actor protobuf descriptors. Add regression coverage for factory invocation count and descriptor registration.
Replace the virtual LocalCache grain and ClusterIdentity subscription with a
named member-local system actor subscribed by concrete PID. Await subscription
during startup, then unsubscribe and stop the actor during shutdown.

Remove the obsolete LocalCache grain contract and virtual actor kind while
retaining protobuf descriptor registration for remote Pub/Sub delivery.

Fixes elsa-workflows#173

BREAKING CHANGE: Removes the generated LocalCache grain APIs and changes
StartLocalCacheActor from BackgroundService to IHostedService.
Add real multi-member coverage proving that startup awaits PID subscription,
each member owns one local invalidator, signals are delivered exactly once,
and graceful shutdown removes the subscription and actor.

Verify that the legacy virtual actor kind is removed while its protobuf
message descriptor remains registered.
@greptile-apps

greptile-apps Bot commented Aug 10, 2026

Copy link
Copy Markdown

PR author is not in the allowed authors list.

@DenDeline DenDeline changed the title Subscribe one local cache invalidator PID per cluster member fix(actors): subscribe one local cache invalidator PID per cluster member Aug 19, 2026
@sfmskywalker

Copy link
Copy Markdown
Member

@greptileai

@sfmskywalker sfmskywalker left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maintainer review completed directly on current head 8a8ac83.

Reviewed correctness and lifecycle ordering, multi-member PID ownership, failure cleanup, breaking API removal, test determinism, and security/performance scope. The only actionable finding was missing verification for subscription/unsubscription failure cleanup; this is fixed in 8a8ac83 with two bounded regression tests.

Local validation: distributed-cache integration suite 8/8 plus three repeat runs, actor unit suite 6/6, net8/net9/net10 module build succeeded, and diff check passed. No remaining actionable findings. Copilot is intentionally bypassed; Greptile is unavailable for this contributor due its author allowlist.

@sfmskywalker
sfmskywalker merged commit fa82e1a into elsa-workflows:main Sep 6, 2026
3 checks passed
@sfmskywalker sfmskywalker added this to the 3.9 milestone Sep 6, 2026
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.

ProtoActor: distributed cache does not subscribe one local invalidator per cluster member

2 participants