Files
ScadaBridge/docs/known-issues/2026-07-22-integration-call-routing-is-dead-code.md
Joseph Doherty a5256e9b12 chore(comm): delete dead IntegrationCallRequest routing (Gitea #32)
'Pattern 4: Integration Routing' — RouteIntegrationCallAsync →
SiteEnvelope(IntegrationCallRequest) → SiteCommunicationActor integration
handler — was plumbed end to end but connected at neither end: no
producer (zero callers) and no handler (AkkaHostedService never
registered LocalHandlerType.Integration). It was an early scaffold the
architecture routed around — the brokered External→Central→Site→Central
round-trip is served by the Inbound API's routed-site-script path (the
RouteTo* verbs, driven from CommunicationServiceInstanceRouter), which is
live, tested, and shares IntegrationTimeout.

Decision (#32): delete. Removed the IntegrationCall{Request,Response}
messages, RouteIntegrationCallAsync, the SiteCommunicationActor receive
block + _integrationHandler field + LocalHandlerType.Integration, and the
four tests that covered them (2 actor, 2 message-contract, 1 dispatcher-
reject, 1 mapper-reject). KEPT IntegrationTimeout — it is the live
timeout for the RouteTo* verbs. Updated the exclusion-narrative comments
(proto/mapper/dispatcher), design §4, the components doc timeout table,
and marked the known-issue RESOLVED.

Full solution build clean (0/0); Communication 634 + Host 421 green.
Net -172/+20 across 14 files. Not in the gRPC proto (was deliberately
excluded there), so no wire-format change.
2026-07-23 14:27:32 -04:00

4.1 KiB
Raw Permalink Blame History

Integration call routing (IntegrationCallRequest) is dead on both ends

Date: 2026-07-22 · Status: RESOLVED (DELETED 2026-07-23) · Tracked: Gitea #32 (filed 2026-07-23) · Severity: Low (no runtime impact — the path cannot be reached) · Area: CentralSite Communication

Resolution (2026-07-23): Decision = delete (option 1 below). Removed the IntegrationCallRequest/IntegrationCallResponse messages, CommunicationService.RouteIntegrationCallAsync, the SiteCommunicationActor receive block + _integrationHandler field + LocalHandlerType.Integration, and the four tests that covered them. IntegrationTimeout was kept — it is the live timeout for the Inbound API's RouteTo* verbs, which are the actual implementation of this "External → Central → Site → Central" pattern (design §4). The narrative comments that documented the exclusion (proto/mapper/dispatcher) were updated. Full solution build clean; Communication suite 634 green. This note is retained as the record.

What

"Pattern 4: Integration Routing" — CommunicationService.RouteIntegrationCallAsyncSiteEnvelope(IntegrationCallRequest)SiteCommunicationActor → an integration handler — is plumbed end to end but connected at neither end.

  • No producer. RouteIntegrationCallAsync (CommunicationService.cs, "Pattern 4") has zero callers in src/ or tests/. It is the only one of CommunicationService's command methods with none.
  • No handler. SiteCommunicationActor forwards to _integrationHandler when one is registered, but RegisterLocalHandler(LocalHandlerType.Integration, …) appears only in SiteCommunicationActorTests.cs. AkkaHostedService registers the other three handler types (Artifacts, EventLog, ParkedMessages) and never this one.

So if anything ever did call it, the site would answer IntegrationCallResponse(Success: false, Error: "Integration handler not available") (SiteCommunicationActor.cs, Pattern 4) — and the two tests that exercise the path both register the handler themselves first, which is why the suite has never noticed.

Do not confuse this with the Inbound API's routed-site-script path, which is live, tested, and uses different messages entirely. This is a separate, unused routing pattern that predates it.

Why it is recorded rather than fixed

Found during the recon for the ClusterClient→gRPC transport migration (docs/plans/2026-07-22-clusterclient-to-grpc-plan.md, T0.2), which had to enumerate every command crossing the site↔central boundary. Of the 29 command types, this is the one that is excluded: 28 migrate to the gRPC contract.

Porting it would mean designing a proto contract, a oneof slot and round-trip mapper tests for a verb no caller can invoke and no site can service — and enshrining it on a wire format whose evolution rules are additive-only, so an unused RPC slot is permanent. Deleting it during a transport migration would mix an unrelated behavioural change into a change whose whole value is that behaviour is identical. Hence: excluded from the contract, behaviour untouched, decision deferred to its own change.

Decision needed

Either:

  1. Delete — remove RouteIntegrationCallAsync, the IntegrationCallRequest/Response messages, the SiteCommunicationActor receive block, LocalHandlerType.Integration, and the three tests that cover them. This is the default if no consumer is planned.
  2. Wire — register a real integration handler on site nodes and give the method a caller. This only makes sense if there is a requirement it serves; none is recorded in docs/requirements/.

Whichever is chosen, do it before Phase 4 of the migration, since Phase 4 deletes the Akka transport underneath this path. If it is still dead at that point, option 1 is forced.

Filing

To be filed as a Gitea issue on dohertj2/scadabridge by the repo owner — this note is the in-repo record of the finding and of the migration exclusion it justifies.