Skip to content

Commit 74a78d2

Browse files
committed
[feat gw-api]add dedupe in route mapper
1 parent aa19e8c commit 74a78d2

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

pkg/gateway/routeutils/route_listener_mapper.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ func (ltr *listenerToRouteMapperImpl) mapGatewayAndRoutes(ctx context.Context, g
4848
}
4949
}
5050

51+
// Dedupe - Check if route already exists for this port before adding
52+
seenRoutesPerPort := make(map[int]map[types.NamespacedName]bool)
5153
// Next, greedily looking for the route to attach to.
5254
for _, listener := range gw.Spec.Listeners {
5355
// used for cross serving check
@@ -74,14 +76,20 @@ func (ltr *listenerToRouteMapperImpl) mapGatewayAndRoutes(ctx context.Context, g
7476

7577
if allowedAttachment {
7678
port := int32(listener.Port)
77-
result[int(port)] = append(result[int(port)], route)
79+
routeKey := route.GetRouteNamespacedName()
80+
if seenRoutesPerPort[int(port)] == nil {
81+
seenRoutesPerPort[int(port)] = make(map[types.NamespacedName]bool)
82+
}
83+
if !seenRoutesPerPort[int(port)][routeKey] {
84+
seenRoutesPerPort[int(port)][routeKey] = true
85+
result[int(port)] = append(result[int(port)], route)
86+
}
7887

7988
// Store compatible hostnames per port per route
8089
if compatibleHostnamesByPort[port] == nil {
8190
compatibleHostnamesByPort[port] = make(map[types.NamespacedName][]gwv1.Hostname)
8291
}
8392
// Append hostnames for routes that attach to multiple listeners on the same port
84-
routeKey := route.GetRouteNamespacedName()
8593
compatibleHostnamesByPort[port][routeKey] = append(compatibleHostnamesByPort[port][routeKey], compatibleHostnames...)
8694
}
8795
}

pkg/gateway/routeutils/route_listener_mapper_test.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package routeutils
33
import (
44
"context"
55
"fmt"
6+
"testing"
7+
68
"github.com/go-logr/logr"
79
"github.com/stretchr/testify/assert"
810
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
911
"k8s.io/apimachinery/pkg/types"
1012
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
11-
"testing"
1213
)
1314

1415
type mockListenerAttachmentHelper struct {
@@ -299,6 +300,42 @@ func Test_mapGatewayAndRoutes(t *testing.T) {
299300
name: "no output",
300301
expected: make(map[int][]preLoadRouteDescriptor),
301302
},
303+
{
304+
name: "route attaches to multiple listeners on same port - verify deduplication",
305+
gw: gwv1.Gateway{
306+
ObjectMeta: metav1.ObjectMeta{
307+
Name: "gw1",
308+
Namespace: "ns-gw",
309+
},
310+
Spec: gwv1.GatewaySpec{
311+
Listeners: []gwv1.Listener{
312+
{
313+
Name: "listener1-port80",
314+
Port: gwv1.PortNumber(80),
315+
},
316+
{
317+
Name: "listener2-port80",
318+
Port: gwv1.PortNumber(80),
319+
},
320+
},
321+
},
322+
},
323+
routes: []preLoadRouteDescriptor{route1},
324+
listenerAttachmentMap: map[string]bool{
325+
"listener1-port80-80-route1-ns1": true,
326+
"listener2-port80-80-route1-ns1": true,
327+
},
328+
routeListenerMap: map[string]bool{
329+
"listener1-port80-80-route1-ns1": true,
330+
"listener2-port80-80-route1-ns1": true,
331+
},
332+
routeGatewayMap: map[string]bool{
333+
makeRouteGatewayMapKey(gateway, route1): true,
334+
},
335+
expected: map[int][]preLoadRouteDescriptor{
336+
80: {route1}, // Only one route1, not duplicated
337+
},
338+
},
302339
}
303340

304341
for _, tc := range testCases {

0 commit comments

Comments
 (0)