Make AddRoute idempotent (upsert instead of reject duplicates)

AddRoute now updates an existing route if one already exists for the
same (listener, hostname) pair, instead of returning AlreadyExists.
This makes repeated deploys idempotent — the MCP agent can register
routes on every deploy without needing to remove them first.

- DB: INSERT ... ON CONFLICT DO UPDATE (SQLite upsert)
- In-memory: overwrite existing route unconditionally
- gRPC: error code changed from AlreadyExists to Internal (for real DB errors)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-27 14:01:45 -07:00
parent a60e5cb86a
commit 28321e22f4
6 changed files with 56 additions and 33 deletions

View File

@@ -229,19 +229,29 @@ func TestAddRoute(t *testing.T) {
}
}
func TestAddRouteDuplicate(t *testing.T) {
func TestAddRouteUpsert(t *testing.T) {
env := setup(t)
ctx := context.Background()
// a.test already exists from setup(). Adding again with a different
// backend should succeed (upsert) and update the route.
_, err := env.client.AddRoute(ctx, &pb.AddRouteRequest{
ListenerAddr: ":443",
Route: &pb.Route{Hostname: "a.test", Backend: "127.0.0.1:1111"},
})
if err == nil {
t.Fatal("expected error for duplicate route")
if err != nil {
t.Fatalf("upsert should succeed: %v", err)
}
if s, ok := status.FromError(err); !ok || s.Code() != codes.AlreadyExists {
t.Fatalf("expected AlreadyExists, got %v", err)
// Verify the route was updated, not duplicated.
routes, err := env.client.ListRoutes(ctx, &pb.ListRoutesRequest{ListenerAddr: ":443"})
if err != nil {
t.Fatalf("list routes: %v", err)
}
for _, r := range routes.Routes {
if r.Hostname == "a.test" && r.Backend != "127.0.0.1:1111" {
t.Fatalf("expected updated backend 127.0.0.1:1111, got %q", r.Backend)
}
}
}