package loadbalancer import ( "net/http" "sync/atomic" F "github.com/yusing/go-proxy/internal/utils/functional" ) type leastConn struct { *LoadBalancer nConn F.Map[*Server, *atomic.Int64] } func (lb *LoadBalancer) newLeastConn() impl { return &leastConn{ LoadBalancer: lb, nConn: F.NewMapOf[*Server, *atomic.Int64](), } } func (impl *leastConn) OnAddServer(srv *Server) { impl.nConn.Store(srv, new(atomic.Int64)) } func (impl *leastConn) OnRemoveServer(srv *Server) { impl.nConn.Delete(srv) } func (impl *leastConn) ServeHTTP(srvs servers, rw http.ResponseWriter, r *http.Request) { srv := srvs[0] minConn, ok := impl.nConn.Load(srv) if !ok { logger.Errorf("[BUG] server %s not found", srv.Name) http.Error(rw, "Internal error", http.StatusInternalServerError) } for i := 1; i < len(srvs); i++ { nConn, ok := impl.nConn.Load(srvs[i]) if !ok { logger.Errorf("[BUG] server %s not found", srv.Name) http.Error(rw, "Internal error", http.StatusInternalServerError) } if nConn.Load() < minConn.Load() { minConn = nConn srv = srvs[i] } } minConn.Add(1) srv.ServeHTTP(rw, r) minConn.Add(-1) }