From 75d272be14664aedc54a95b2e47da407f5e7e7c4 Mon Sep 17 00:00:00 2001
From: yusing <yusing@6uo.me>
Date: Mon, 17 Feb 2025 11:16:34 +0800
Subject: [PATCH] fix loadbalancing when two container have the same alias

---
 internal/net/gphttp/loadbalancer/loadbalancer.go | 12 ++++++------
 internal/net/gphttp/loadbalancer/types/server.go |  9 ++++++---
 internal/route/reverse_proxy.go                  |  2 +-
 internal/route/route.go                          |  2 +-
 4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/internal/net/gphttp/loadbalancer/loadbalancer.go b/internal/net/gphttp/loadbalancer/loadbalancer.go
index fa3e413..29603ea 100644
--- a/internal/net/gphttp/loadbalancer/loadbalancer.go
+++ b/internal/net/gphttp/loadbalancer/loadbalancer.go
@@ -125,12 +125,12 @@ func (lb *LoadBalancer) AddServer(srv Server) {
 	lb.poolMu.Lock()
 	defer lb.poolMu.Unlock()
 
-	if lb.pool.Has(srv.Name()) {
-		old, _ := lb.pool.Load(srv.Name())
+	if lb.pool.Has(srv.Key()) {
+		old, _ := lb.pool.Load(srv.Key())
 		lb.sumWeight -= old.Weight()
 		lb.impl.OnRemoveServer(old)
 	}
-	lb.pool.Store(srv.Name(), srv)
+	lb.pool.Store(srv.Key(), srv)
 	lb.sumWeight += srv.Weight()
 
 	lb.rebalance()
@@ -146,11 +146,11 @@ func (lb *LoadBalancer) RemoveServer(srv Server) {
 	lb.poolMu.Lock()
 	defer lb.poolMu.Unlock()
 
-	if !lb.pool.Has(srv.Name()) {
+	if !lb.pool.Has(srv.Key()) {
 		return
 	}
 
-	lb.pool.Delete(srv.Name())
+	lb.pool.Delete(srv.Key())
 
 	lb.sumWeight -= srv.Weight()
 	lb.rebalance()
@@ -244,7 +244,7 @@ func (lb *LoadBalancer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
 func (lb *LoadBalancer) MarshalJSON() ([]byte, error) {
 	extra := make(map[string]any)
 	lb.pool.RangeAll(func(k string, v Server) {
-		extra[v.Name()] = v
+		extra[v.Key()] = v
 	})
 
 	return (&monitor.JSONRepresentation{
diff --git a/internal/net/gphttp/loadbalancer/types/server.go b/internal/net/gphttp/loadbalancer/types/server.go
index e0e7b5e..a409b6e 100644
--- a/internal/net/gphttp/loadbalancer/types/server.go
+++ b/internal/net/gphttp/loadbalancer/types/server.go
@@ -26,6 +26,7 @@ type (
 		http.Handler
 		health.HealthMonitor
 		Name() string
+		Key() string
 		URL() *net.URL
 		Weight() Weight
 		SetWeight(weight Weight)
@@ -63,6 +64,10 @@ func (srv *server) URL() *net.URL {
 	return srv.url
 }
 
+func (srv *server) Key() string {
+	return srv.url.Host
+}
+
 func (srv *server) Weight() Weight {
 	return srv.weight
 }
@@ -78,9 +83,7 @@ func (srv *server) String() string {
 func (srv *server) TryWake() error {
 	waker, ok := srv.Handler.(idlewatcher.Waker)
 	if ok {
-		if err := waker.Wake(); err != nil {
-			return err
-		}
+		return waker.Wake()
 	}
 	return nil
 }
diff --git a/internal/route/reverse_proxy.go b/internal/route/reverse_proxy.go
index 7500122..b021e74 100755
--- a/internal/route/reverse_proxy.go
+++ b/internal/route/reverse_proxy.go
@@ -97,7 +97,7 @@ func (r *ReveseProxyRoute) String() string {
 
 // Start implements task.TaskStarter.
 func (r *ReveseProxyRoute) Start(parent task.Parent) gperr.Error {
-	if existing, ok := routes.GetHTTPRoute(r.TargetName()); ok {
+	if existing, ok := routes.GetHTTPRoute(r.TargetName()); ok && !r.UseLoadBalance() {
 		return gperr.Errorf("route already exists: from provider %s and %s", existing.ProviderName(), r.ProviderName())
 	}
 	r.task = parent.Subtask("http."+r.TargetName(), false)
diff --git a/internal/route/route.go b/internal/route/route.go
index 56bf003..613d618 100644
--- a/internal/route/route.go
+++ b/internal/route/route.go
@@ -100,7 +100,7 @@ func (r *Route) Validate() (err gperr.Error) {
 	}
 
 	if !r.UseHealthCheck() && (r.UseLoadBalance() || r.UseIdleWatcher()) {
-		errs.Adds("healthCheck.disable cannot be true when loadbalancer or idlewatcher is enabled")
+		errs.Adds("cannot disable healthcheck when loadbalancer or idle watcher is enabled")
 	}
 
 	if errs.HasError() {