From aab1d784463d708426fa9218c1167586eccebf2a Mon Sep 17 00:00:00 2001 From: DanB Date: Mon, 18 Feb 2019 13:20:19 +0100 Subject: [PATCH] DispatcherS - new strategies for *random and *round_robin --- dispatchers/libdispatcher.go | 54 +++++++++++++++++++++++++++++++++++- utils/consts.go | 33 +++++++++++----------- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/dispatchers/libdispatcher.go b/dispatchers/libdispatcher.go index 460d94591..657f1fc89 100644 --- a/dispatchers/libdispatcher.go +++ b/dispatchers/libdispatcher.go @@ -42,6 +42,10 @@ func newDispatcher(pfl *engine.DispatcherProfile) (d Dispatcher, err error) { switch pfl.Strategy { case utils.MetaWeight: d = &WeightDispatcher{conns: pfl.Conns.Clone()} + case utils.MetaRandom: + d = &RandomDispatcher{conns: pfl.Conns.Clone()} + case utils.MetaRoundRobin: + d = &RoundRobinDispatcher{conns: pfl.Conns.Clone()} default: err = fmt.Errorf("unsupported dispatch strategy: <%s>", pfl.Strategy) } @@ -57,7 +61,7 @@ type WeightDispatcher struct { func (wd *WeightDispatcher) SetProfile(pfl *engine.DispatcherProfile) { wd.Lock() pfl.Conns.Sort() - wd.conns = pfl.Conns.Clone() + wd.conns = pfl.Conns.Clone() // avoid concurrency on profile wd.Unlock() return } @@ -68,3 +72,51 @@ func (wd *WeightDispatcher) ConnIDs() (connIDs []string) { wd.RUnlock() return } + +// RandomDispatcher selects the next connection randomly +// together with RouteID can serve as load-balancer +type RandomDispatcher struct { + sync.RWMutex + conns engine.DispatcherConns +} + +func (d *RandomDispatcher) SetProfile(pfl *engine.DispatcherProfile) { + d.Lock() + d.conns = pfl.Conns.Clone() + d.Unlock() + return +} + +func (d *RandomDispatcher) ConnIDs() (connIDs []string) { + d.RLock() + conns := d.conns.Clone() + d.RUnlock() + conns.Shuffle() // randomize the connections + return conns.ConnIDs() +} + +// RoundRobinDispatcher selects the next connection in round-robin fashion +type RoundRobinDispatcher struct { + sync.RWMutex + conns engine.DispatcherConns + connIdx int // used for the next connection +} + +func (d *RoundRobinDispatcher) SetProfile(pfl *engine.DispatcherProfile) { + d.Lock() + d.conns = pfl.Conns.Clone() + d.Unlock() + return +} + +func (d *RoundRobinDispatcher) ConnIDs() (connIDs []string) { + d.RLock() + conns := d.conns.Clone() + conns.ReorderFromIndex(d.connIdx) + d.connIdx++ + if d.connIdx >= len(d.conns) { + d.connIdx = 0 + } + d.RUnlock() + return conns.ConnIDs() +} diff --git a/utils/consts.go b/utils/consts.go index f6faae712..d6095b515 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -671,22 +671,23 @@ const ( // Dispatcher Const const ( - MetaFirst = "*first" - MetaRandom = "*random" - MetaBroadcast = "*broadcast" - MetaNext = "*next" - ThresholdSv1 = "ThresholdSv1" - StatSv1 = "StatSv1" - ResourceSv1 = "ResourceSv1" - SupplierSv1 = "SupplierSv1" - AttributeSv1 = "AttributeSv1" - SessionSv1 = "SessionSv1" - ChargerSv1 = "ChargerSv1" - MetaAuth = "*auth" - APIKey = "APIKey" - APIMethods = "APIMethods" - APIMethod = "APIMethod" - NestingSep = "." + MetaFirst = "*first" + MetaRandom = "*random" + MetaBroadcast = "*broadcast" + MetaNext = "*next" + MetaRoundRobin = "*round_robin" + ThresholdSv1 = "ThresholdSv1" + StatSv1 = "StatSv1" + ResourceSv1 = "ResourceSv1" + SupplierSv1 = "SupplierSv1" + AttributeSv1 = "AttributeSv1" + SessionSv1 = "SessionSv1" + ChargerSv1 = "ChargerSv1" + MetaAuth = "*auth" + APIKey = "APIKey" + APIMethods = "APIMethods" + APIMethod = "APIMethod" + NestingSep = "." ) // ApierV1 APIs