Skip to content

feat(actors): add configurable Proto.Actor Pub/Sub subscriber storage - #172

Merged
sfmskywalker merged 5 commits into
elsa-workflows:mainfrom
DenDeline:feature/169-configurable-pubsub-subscriber-store
Sep 6, 2026
Merged

feat(actors): add configurable Proto.Actor Pub/Sub subscriber storage#172
sfmskywalker merged 5 commits into
elsa-workflows:mainfrom
DenDeline:feature/169-configurable-pubsub-subscriber-store

Conversation

@DenDeline

@DenDeline DenDeline commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Make Proto.Actor Pub/Sub subscriber storage configurable and persistent across topic reactivation, with an optional Redis-backed provider for clustered deployments.

Fixes #169.

Changes

  • Add CreatePubSubSubscribersStore to ProtoActorFeature.
  • Register one stable subscriber store per service provider/member.
  • Explicitly register exactly one TopicActor.Kind, while preserving existing manual store and topic-kind registrations.
  • Resolve the store lazily when a topic actor is produced.
  • Provide a process-local in-memory default that survives topic reactivation on the same host.
  • Add the optional Elsa.Actors.ProtoActor.PubSub.Redis module with protobuf serialization, configurable database resolution, key prefix, and complete key formatter.
  • Document that clustered members must share the same durable Redis database and deterministic key configuration.
  • Add focused coverage for DI lifetime, lazy resolution, compatibility, serialization, key generation, feature composition, and cancellation.

Compatibility

This is additive. Existing IKeyValueStore<Subscribers> or manual TopicActor.Kind registrations remain authoritative. The core Proto.Actor package does not gain a Redis dependency.

The default store is process-local only; it does not survive process restarts or cross-member migration. Clustered deployments should configure shared durable storage.

Validation

  • dotnet test test/modules/actors/Elsa.Actors.ProtoActor.UnitTests/Elsa.Actors.ProtoActor.UnitTests.csproj --configuration Release --no-restore: 23 passed.
  • dotnet build src/modules/actors/Elsa.Actors.ProtoActor.PubSub.Redis/Elsa.Actors.ProtoActor.PubSub.Redis.csproj --configuration Release --no-restore: .NET 8, 9, and 10 succeeded with zero warnings and zero errors.
  • dotnet list ... package --vulnerable --include-transitive --no-restore: no vulnerable packages.
  • git diff --check origin/main...HEAD: passed.

Review status

Greptile verified one P2 cancellation issue on the earlier head. Contributor commit 391bca3 fixed it, current head 5e3eaa7 adds regression tests, and the review thread has a direct maintainer reply. Greptile then explicitly declined current-head review because the contributor is outside its author allowlist, so the historical score is not reused. Worker self-review and root current-head review found no remaining actionable issue. Fresh GitHub CI remains the merge gate.

Scope

This PR covers subscriber-store configuration, the process-local default, the optional Redis provider, and focused tests. It does not change cluster lifecycle, member-local cache invalidation, or protobuf remote registration, which were delivered separately in #168, #174, and #171.

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

Fixes elsa-workflows#167
- register TopicActor with a configurable subscriber store
- add Redis-backed storage with configurable keys
- preserve existing store and TopicActor registrations
- cover core and Redis configuration with unit tests

Refs elsa-workflows#169
@DenDeline

Copy link
Copy Markdown
Contributor Author

For easier review, this comparison shows only this PR’s changes and excludes dependency #168: review the focused diff. It contains one commit across 13 files

@DenDeline DenDeline changed the title Add configurable Proto.Actor Pub/Sub subscriber storage feat(actors): add configurable Proto.Actor Pub/Sub subscriber storage Aug 19, 2026
@sfmskywalker

Copy link
Copy Markdown
Member

@greptileai

@greptile-apps

greptile-apps Bot commented Aug 19, 2026

Copy link
Copy Markdown

Greptile Summary

This change makes Proto.Actor Pub/Sub subscriber persistence configurable and adds an optional Redis-backed store with configurable key generation. Direct execution confirmed that the in-memory store applies reads and state changes even when its cancellation token is already canceled. Add cancellation guards before merge so aborted operations cannot update subscriber state.

Confidence Score: 4/5

Not merge-safe until canceled subscriber-store operations stop reading or mutating state.

One verified non-security P2 finding remains. Under the scoring rules, a nonempty set containing only P2 findings scores 4.

Files Needing Attention: src/modules/actors/Elsa.Actors.ProtoActor/Services/InMemorySubscribersStore.cs

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for the posted P2 finding and linked it to the review comment.
  • T-Rex executed the cancellation harness to exercise the subscriber-store path described in the finding and began validating the observed behavior.
  • A baseline subscriber-store behavior log was captured to establish the expected execution flow.
  • A canceled-token subscriber-store behavior log was captured to compare against the baseline and verify the impact of cancellation.
  • Artifacts were uploaded and organized for reviewer inspection, including the executable cancellation harness source and the two behavior logs.

View all artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix All With AI
### Issue 1
src/modules/actors/Elsa.Actors.ProtoActor/Services/InMemorySubscribersStore.cs:11-26
**Canceled operations still mutate in-memory subscriber state**

`InMemorySubscribersStore` accepts a `CancellationToken` but never observes it. A canceled `SetAsync` replaces the stored subscribers and a canceled `ClearAsync` removes them instead of throwing before any state change. This differs from the Redis implementation and allows shutdown or aborted Pub/Sub operations to commit changes after their caller has canceled them. Call `ct.ThrowIfCancellationRequested()` at the start of each store operation.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "Add configurable Pub/Sub subscriber stor..." | Re-trigger Greptile

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown

PR author is not in the allowed authors list.

@sfmskywalker
sfmskywalker requested a balanced review from Copilot September 6, 2026 22:43

@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.

Reviewed current head 5e3eaa7 against issue #169 and current main. The scoped DI registration, lazy TopicActor store resolution, manual-registration preservation, Redis package boundary, cancellation behavior, and regression coverage are coherent. Independent validation passes 23/23 focused tests, .NET 8/9/10 builds, vulnerability scan, and diff check.

@sfmskywalker
sfmskywalker merged commit 3e83b5d into elsa-workflows:main Sep 6, 2026
3 checks passed
@DenDeline
DenDeline removed the request for review from Copilot September 6, 2026 23:17
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: make Pub/Sub subscriber storage configurable and durable across topic reactivation

2 participants