Problem
SlackThreadBindingActor and SignalRSessionActor duplicate ~80 lines of identical pipeline lifecycle code:
EnsureInitializedAsync() — creates ActorMaterializer, runs pipeline, materializes input/output, registers OutputStreamTerminated continuation
ReinitializePipelineAsync(string reason) — completes input queue, disposes session, disposes materializer, re-initializes
PostStop() — identical three-line teardown
- Private message types:
OutputStreamTerminated(int Generation, Exception? Cause), ReinitializePipeline(string Reason)
SignalRSessionActor even acknowledges this with the comment: "Mirrors the pattern used by SlackThreadBindingActor".
Proposed Solution
Create an abstract PipelineHostingActor base class in src/Netclaw.Actors/Channels/ that consolidates the shared lifecycle code. Subclasses override:
Pipeline — the ISessionPipeline to use
PipelineOptions — channel-specific SessionPipelineOptions
OnOutput(SessionOutput) — how to route output to the actor's mailbox
Both actors would extend PipelineHostingActor instead of ReceiveActor.
Risk
High — touches Akka actor lifecycle. Requires careful testing of both Slack and SignalR session flows.
Files
src/Netclaw.Channels/Slack/SlackThreadBindingActor.cs
src/Netclaw.Daemon/Gateway/SignalRSessionActor.cs
- New:
src/Netclaw.Actors/Channels/PipelineHostingActor.cs
Context
Identified during the code quality audit in #302.
Problem
SlackThreadBindingActorandSignalRSessionActorduplicate ~80 lines of identical pipeline lifecycle code:EnsureInitializedAsync()— creates ActorMaterializer, runs pipeline, materializes input/output, registers OutputStreamTerminated continuationReinitializePipelineAsync(string reason)— completes input queue, disposes session, disposes materializer, re-initializesPostStop()— identical three-line teardownOutputStreamTerminated(int Generation, Exception? Cause),ReinitializePipeline(string Reason)SignalRSessionActoreven acknowledges this with the comment:"Mirrors the pattern used by SlackThreadBindingActor".Proposed Solution
Create an abstract
PipelineHostingActorbase class insrc/Netclaw.Actors/Channels/that consolidates the shared lifecycle code. Subclasses override:Pipeline— theISessionPipelineto usePipelineOptions— channel-specificSessionPipelineOptionsOnOutput(SessionOutput)— how to route output to the actor's mailboxBoth actors would extend
PipelineHostingActorinstead ofReceiveActor.Risk
High — touches Akka actor lifecycle. Requires careful testing of both Slack and SignalR session flows.
Files
src/Netclaw.Channels/Slack/SlackThreadBindingActor.cssrc/Netclaw.Daemon/Gateway/SignalRSessionActor.cssrc/Netclaw.Actors/Channels/PipelineHostingActor.csContext
Identified during the code quality audit in #302.