fix(backend): resolve federation forward traffic stats and listener disappearance (#208)

* fix(backend): add repository methods for federation forward runtime management

- GetActiveForwardPeerShareRuntimeByServiceName: lookup runtime by share_id and service_name
- MarkForwardPeerShareRuntimeReleasedByServiceName: release runtime by service_name
- ListActiveForwardPeerShareRuntimesByNodeAndServiceName: node-scoped query for flow processing

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix(backend): bind and release federation forward runtimes on service commands

- bindPeerShareForwardRuntimeServices: create runtime if missing, update ServiceName/Port/Applied/Status
- releasePeerShareForwardRuntimeServices: handle deleteservice command to mark runtime released
- parseFederationForwardServiceNamesForRelease: extract service names from delete payload
- Tests: bind creates runtime when missing, release marks runtime as released

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix(backend): scope federation flow lookup by node to avoid cross-share collisions

- flowUpload: use GetNodeBySecret to extract nodeID for flow processing
- processFlowItem: accept nodeID parameter and pass to flow handlers
- processPeerShareFlowByServiceName: try node-scoped query first, fallback to global
- Add warning log when multiple runtimes match (ambiguous)
- Tests: update all processFlowItem calls with nodeID parameter

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* test(contract): adjust federation dual panel contract expectations

Update assertion for entry share runtime binding behavior after fix

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
sagit
2026-02-25 14:10:24 +08:00
committed by GitHub
parent 0eed74fe10
commit 7ba90e8696
7 changed files with 328 additions and 25 deletions
@@ -44,7 +44,7 @@ func TestProcessFlowItemTracksPeerShareFlowAndEnforcesLimit(t *testing.T) {
}
h := &Handler{repo: r}
h.processFlowItem(flowItem{N: "fed_svc_17", U: 1200, D: 900})
h.processFlowItem(1, flowItem{N: "fed_svc_17", U: 1200, D: 900})
updatedShare, err := r.GetPeerShare(share.ID)
if err != nil || updatedShare == nil {
@@ -120,7 +120,7 @@ func TestProcessFlowItemTracksPeerShareFlowForFederationPortForward(t *testing.T
}
h := &Handler{repo: r}
h.processFlowItem(flowItem{N: "20_2_10", U: 120, D: 80})
h.processFlowItem(1, flowItem{N: "20_2_10", U: 120, D: 80})
updatedShare, err := r.GetPeerShare(share.ID)
if err != nil || updatedShare == nil {
@@ -166,7 +166,7 @@ func TestProcessFlowItemTracksPeerShareFlowByForwardServiceName(t *testing.T) {
}
h := &Handler{repo: r}
h.processFlowItem(flowItem{N: "20_2_10_tcp", U: 120, D: 80})
h.processFlowItem(1, flowItem{N: "20_2_10_tcp", U: 120, D: 80})
updatedShare, err := r.GetPeerShare(share.ID)
if err != nil || updatedShare == nil {
@@ -226,7 +226,7 @@ func TestProcessFlowItemFallsBackToServiceNameWhenForwardIDCollidesAcrossPanels(
}
h := &Handler{repo: r}
h.processFlowItem(flowItem{N: "20_2_10_tcp", U: 120, D: 80})
h.processFlowItem(1, flowItem{N: "20_2_10_tcp", U: 120, D: 80})
updatedShare, err := r.GetPeerShare(share.ID)
if err != nil || updatedShare == nil {
@@ -288,7 +288,7 @@ func TestProcessFlowItemSkipsPeerShareFlowWhenServiceNameIsAmbiguous(t *testing.
}
h := &Handler{repo: r}
h.processFlowItem(flowItem{N: "99_2_10_tcp", U: 120, D: 80})
h.processFlowItem(1, flowItem{N: "99_2_10_tcp", U: 120, D: 80})
updatedA, _ := r.GetPeerShare(shareA.ID)
updatedB, _ := r.GetPeerShare(shareB.ID)