@@ -701,3 +701,81 @@ func BenchmarkWeightedRoundRobinAlgorithm(b *testing.B) {
701701 })
702702 }
703703}
704+
705+ func TestConsistentHashBoundedLoadSearchSkipsFilteredEndpoints (t * testing.T ) {
706+ endpoints := []string {
707+ "http://127.0.0.1:8080" ,
708+ "http://127.0.0.2:8080" ,
709+ "http://127.0.0.3:8080" ,
710+ }
711+ request , err := http .NewRequest ("GET" , "http://127.0.0.1:1234/foo" , nil )
712+ require .NoError (t , err )
713+
714+ route := NewAlgorithmProvider ().Do ([]* routing.Route {{
715+ Route : eskip.Route {
716+ BackendType : eskip .LBBackend ,
717+ LBAlgorithm : ConsistentHash .String (),
718+ LBEndpoints : eskip .NewLBEndpoints (endpoints ),
719+ },
720+ }})[0 ]
721+
722+ endpointRegistry := routing .NewEndpointRegistry (routing.RegistryOptions {})
723+ defer endpointRegistry .Close ()
724+ endpointRegistry .Do ([]* routing.Route {route })
725+
726+ ch := route .LBAlgorithm .(* consistentHash )
727+
728+ var key string
729+ var selectedIndex int
730+ var skippedIndex int
731+
732+ for ringIndex , ringEntry := range ch .hashRing {
733+ nextIndex := ch .hashRing [(ringIndex + 1 )% ch .Len ()].index
734+ if ringEntry .index == nextIndex {
735+ continue
736+ }
737+
738+ for vnode := 0 ; vnode < 100 ; vnode ++ {
739+ candidateKey := fmt .Sprintf ("%s-%d" , endpoints [ringEntry .index ], vnode )
740+ if hash (candidateKey ) == ringEntry .hash {
741+ key = candidateKey
742+ selectedIndex = ringEntry .index
743+ skippedIndex = nextIndex
744+ break
745+ }
746+ }
747+
748+ if key != "" {
749+ break
750+ }
751+ }
752+
753+ require .NotEmpty (t , key )
754+
755+ filteredEndpoints := make ([]routing.LBEndpoint , 0 , len (route .LBEndpoints )- 1 )
756+
757+ for i , endpoint := range route .LBEndpoints {
758+ if i != skippedIndex {
759+ filteredEndpoints = append (filteredEndpoints , endpoint )
760+ }
761+ }
762+
763+ addInflightRequests (endpointRegistry , route .LBEndpoints [selectedIndex ], 20 )
764+
765+ ctx := & routing.LBContext {
766+ Request : request ,
767+ Route : route ,
768+ LBEndpoints : filteredEndpoints ,
769+ Params : map [string ]interface {}{
770+ ConsistentHashKey : key ,
771+ ConsistentHashBalanceFactor : 1.25 ,
772+ },
773+ }
774+
775+ selected := ch .Apply (ctx )
776+
777+ if selected .Host == route .LBEndpoints [skippedIndex ].Host {
778+ t .Fatalf ("selected filtered endpoint %q" , selected .Host )
779+ }
780+
781+ }
0 commit comments