mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 20:52:33 +02:00
53 lines
1.1 KiB
Go
53 lines
1.1 KiB
Go
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 {
|
|
impl.l.Error().Msgf("[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 {
|
|
impl.l.Error().Msgf("[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)
|
|
}
|