@@ -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,26 @@ func (b *ArchitectureAwareBalancer) Next(c echo.Context) *middleware.ProxyTarget
6468 b .mu .Lock ()
6569 defer b .mu .Unlock ()
6670
71+ if ! isInvoke (c ) {
72+ // fallback to round-robin
73+ var candidate * middleware.ProxyTarget
74+ var arch string
75+ if len (b .armRing .targetList ) > 0 {
76+ arch = b .selectArchitectureRR ()
77+ } else {
78+ arch = container .X86
79+ }
80+
81+ if arch == container .ARM {
82+ b .armRRIndex = (b .armRRIndex + 1 ) % len (b .armRing .targetList )
83+ candidate = b .armRing .targetList [b .armRRIndex ]
84+ } else {
85+ b .x86RRIndex = (b .x86RRIndex + 1 ) % len (b .x86Ring .targetList )
86+ candidate = b .x86Ring .targetList [b .x86RRIndex ]
87+ }
88+ return candidate
89+ }
90+
6791 funcName := extractFunctionName (c ) // get function's name from request's URL
6892 fun , ok := function .GetFunction (funcName ) // we use this to leverage cache before asking etcd
6993 if ! ok {
@@ -88,7 +112,7 @@ func (b *ArchitectureAwareBalancer) Next(c echo.Context) *middleware.ProxyTarget
88112 bandit := mab .GlobalBanditManager .GetBandit (funcName )
89113 targetArch = bandit .SelectArm (ctx )
90114 } else if b .mode == RR { // RoundRobin
91- targetArch = b .selectArchitectureRR (funcName ) // here the load balancer decides what architecture to use for this function
115+ targetArch = b .selectArchitectureRR () // here the load balancer decides what architecture to use for this function
92116 } else { // Random
93117 targetArch = b .selectArchitectureRandom () // random load balancer for testing purposes
94118 }
@@ -196,14 +220,14 @@ func (b *ArchitectureAwareBalancer) selectArchitecture(fun *function.Function) (
196220}
197221
198222// selectArchitectureRR selects the architecture using a Round Robin policy.
199- func (b * ArchitectureAwareBalancer ) selectArchitectureRR (funcName string ) string {
223+ func (b * ArchitectureAwareBalancer ) selectArchitectureRR () string {
200224
201225 // This is just a function to use as a baseline for the LB. It should actually implement checks over the rings dimension.
202226 // i.e.: it cannot select ARM/X86 "blindly", it should check if we have at least one node for that architecture.
203227 archs := []string {container .ARM , container .X86 }
204- index := b .rrIndices [ funcName ]
228+ index := b .archRRIndex
205229 selected := archs [index ]
206- b .rrIndices [ funcName ] = (index + 1 ) % len (archs )
230+ b .archRRIndex = (index + 1 ) % len (archs )
207231 return selected
208232}
209233
0 commit comments