proxy-loadbalancer/src/proxy/proxy.go

80 lines
2.2 KiB
Go

package proxy
import (
"github.com/sirupsen/logrus"
"main/logging"
"slices"
"sync"
"sync/atomic"
)
type ForwardProxyCluster struct {
mu sync.RWMutex
ourOnlineProxies []string
ourOfflineProxies []string
thirdpartyOnlineProxies []string
thirdpartyBrokenProxies []string
thirdpartyOfflineProxies []string
ipAddresses []string
BalancerReady WaitGroupCountable
BalancerOnline bool
currentProxyAll int32
currentProxyOurs int32
currentProxyAllWithBroken int32
refreshInProgress bool
}
var log *logrus.Logger
func init() {
log = logging.GetLogger()
}
func NewForwardProxyCluster() *ForwardProxyCluster {
p := &ForwardProxyCluster{}
atomic.StoreInt32(&p.currentProxyAll, 0)
atomic.StoreInt32(&p.currentProxyOurs, 0)
atomic.StoreInt32(&p.currentProxyAllWithBroken, 0)
p.BalancerReady.Add(1)
p.BalancerOnline = false
return p
}
func (p *ForwardProxyCluster) cycleProxy(validProxies []string, currentProxy *int32) string {
// Just round robin
p.mu.RLock()
defer p.mu.RUnlock()
currProxy := int(atomic.LoadInt32(currentProxy))
if currProxy > len(validProxies)-1 {
// This might happen if the background thread is currently making changes to the list of proxies.
// Just set it to the current length of the proxies array and move on.
currProxy = len(validProxies) - 1
}
downstreamProxy := validProxies[currProxy]
newCurrentProxy := (currProxy + 1) % len(validProxies)
atomic.StoreInt32(currentProxy, int32(newCurrentProxy))
return downstreamProxy
}
func (p *ForwardProxyCluster) getProxyFromAll() string {
p.mu.RLock()
defer p.mu.RUnlock()
validProxies := append(p.ourOnlineProxies, p.thirdpartyOnlineProxies...)
return p.cycleProxy(validProxies, &p.currentProxyAll)
}
func (p *ForwardProxyCluster) getProxyFromOurs() string {
p.mu.RLock()
defer p.mu.RUnlock()
validProxies := p.ourOnlineProxies
return p.cycleProxy(validProxies, &p.currentProxyOurs)
}
func (p *ForwardProxyCluster) getProxyFromAllWithBroken() string {
p.mu.RLock()
defer p.mu.RUnlock()
validProxies := slices.Concat(p.ourOnlineProxies, p.thirdpartyBrokenProxies, p.thirdpartyOnlineProxies)
return p.cycleProxy(validProxies, &p.currentProxyAllWithBroken)
}