@@ -24,8 +24,10 @@ type ArchitectureAwareBalancer struct {
2424 armRing * HashRing
2525 x86Ring * HashRing
2626
27- mode string
28- rrIndices map [string ]int
27+ mode string
28+ archRRIndex int
29+ armRRIndex int // for non-invoke requests using RR
30+ x86RRIndex int // for non-invoke requests using RR
2931}
3032
3133// NewArchitectureAwareBalancer Constructor
@@ -37,9 +39,11 @@ func NewArchitectureAwareBalancer(targets []*middleware.ProxyTarget) *Architectu
3739 log .Printf ("Running ArchitectureAwareLB with %d replicas per node in the hash rings\n " , REPLICAS )
3840
3941 b := & ArchitectureAwareBalancer {
40- armRing : NewHashRing (REPLICAS ),
41- x86Ring : NewHashRing (REPLICAS ),
42- rrIndices : make (map [string ]int ),
42+ armRing : NewHashRing (REPLICAS ),
43+ x86Ring : NewHashRing (REPLICAS ),
44+ archRRIndex : 0 ,
45+ armRRIndex : 0 ,
46+ x86RRIndex : 0 ,
4347 }
4448
4549 b .mode = config .GetString (config .LB_MODE , RR )
@@ -64,6 +68,29 @@ func (b *ArchitectureAwareBalancer) Next(c echo.Context) *middleware.ProxyTarget
6468 b .mu .Lock ()
6569 defer b .mu .Unlock ()
6670
71+ if ! isInvoke (c ) {
72+ log .Printf ("c NOT INVOKE: %s\n " , c .Path ())
73+ // fallback to round-robin
74+ var candidate * middleware.ProxyTarget
75+ var arch string
76+ if len (b .armRing .targetList ) == 0 {
77+ arch = container .X86
78+ } else if len (b .x86Ring .targetList ) == 0 {
79+ arch = container .ARM
80+ } else {
81+ arch = b .selectArchitectureRR ()
82+ }
83+
84+ if arch == container .ARM {
85+ b .armRRIndex = (b .armRRIndex + 1 ) % len (b .armRing .targetList )
86+ candidate = b .armRing .targetList [b .armRRIndex ]
87+ } else {
88+ b .x86RRIndex = (b .x86RRIndex + 1 ) % len (b .x86Ring .targetList )
89+ candidate = b .x86Ring .targetList [b .x86RRIndex ]
90+ }
91+ return candidate
92+ }
93+
6794 funcName := extractFunctionName (c ) // get function's name from request's URL
6895 fun , ok := function .GetFunction (funcName ) // we use this to leverage cache before asking etcd
6996 if ! ok {
@@ -88,7 +115,7 @@ func (b *ArchitectureAwareBalancer) Next(c echo.Context) *middleware.ProxyTarget
88115 bandit := mab .GlobalBanditManager .GetBandit (funcName )
89116 targetArch = bandit .SelectArm (ctx )
90117 } else if b .mode == RR { // RoundRobin
91- targetArch = b .selectArchitectureRR (funcName ) // here the load balancer decides what architecture to use for this function
118+ targetArch = b .selectArchitectureRR () // here the load balancer decides what architecture to use for this function
92119 } else { // Random
93120 targetArch = b .selectArchitectureRandom () // random load balancer for testing purposes
94121 }
@@ -196,14 +223,14 @@ func (b *ArchitectureAwareBalancer) selectArchitecture(fun *function.Function) (
196223}
197224
198225// selectArchitectureRR selects the architecture using a Round Robin policy.
199- func (b * ArchitectureAwareBalancer ) selectArchitectureRR (funcName string ) string {
226+ func (b * ArchitectureAwareBalancer ) selectArchitectureRR () string {
200227
201228 // This is just a function to use as a baseline for the LB. It should actually implement checks over the rings dimension.
202229 // i.e.: it cannot select ARM/X86 "blindly", it should check if we have at least one node for that architecture.
203230 archs := []string {container .ARM , container .X86 }
204- index := b .rrIndices [ funcName ]
231+ index := b .archRRIndex
205232 selected := archs [index ]
206- b .rrIndices [ funcName ] = (index + 1 ) % len (archs )
233+ b .archRRIndex = (index + 1 ) % len (archs )
207234 return selected
208235}
209236
0 commit comments