'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.
4.1 KiB
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: Central–Site Communication
Resolution (2026-07-23): Decision = delete (option 1 below). Removed the
IntegrationCallRequest/IntegrationCallResponsemessages,CommunicationService.RouteIntegrationCallAsync, theSiteCommunicationActorreceive block +_integrationHandlerfield +LocalHandlerType.Integration, and the four tests that covered them.IntegrationTimeoutwas kept — it is the live timeout for the Inbound API'sRouteTo*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.RouteIntegrationCallAsync →
SiteEnvelope(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 insrc/ortests/. It is the only one ofCommunicationService's command methods with none. - No handler.
SiteCommunicationActorforwards to_integrationHandlerwhen one is registered, butRegisterLocalHandler(LocalHandlerType.Integration, …)appears only inSiteCommunicationActorTests.cs.AkkaHostedServiceregisters 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:
- Delete — remove
RouteIntegrationCallAsync, theIntegrationCallRequest/Responsemessages, theSiteCommunicationActorreceive block,LocalHandlerType.Integration, and the three tests that cover them. This is the default if no consumer is planned. - 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.