custom server selection (#82)

This commit is contained in:
David Colburn
2024-02-08 16:13:57 -08:00
committed by GitHub
parent 84d7ae1253
commit 0611542c99
3 changed files with 36 additions and 48 deletions
-7
View File
@@ -60,13 +60,6 @@ func getRequestOpts(i *info.RequestInfo, options psrpc.ClientOpts, opts ...psrpc
opt(o)
}
if o.SelectionOpts.Jitter < 0 {
o.SelectionOpts.Jitter = 0
}
if o.SelectionOpts.Jitter > 1 {
o.SelectionOpts.Jitter = 1
}
return *o
}
+25 -35
View File
@@ -17,8 +17,6 @@ package client
import (
"context"
"errors"
r "math/rand"
"sort"
"time"
"google.golang.org/protobuf/proto"
@@ -178,52 +176,44 @@ func selectServer(
time.AfterFunc(opts.AffinityTimeout, cancel)
}
shorted := false
var resErr error
var claims []*internal.ClaimRequest
var resCount int
var (
shorted bool
serverID string
affinity float32
claims []*psrpc.Claim
claimCount int
resErr error
)
for {
select {
case <-ctx.Done():
if len(claims) > 0 {
sort.Slice(claims, func(i, j int) bool {
return claims[i].Affinity > claims[j].Affinity
})
best := claims[0].Affinity
minAffinity := best * (1 - opts.Jitter)
i := 0
for ; i < len(claims); i++ {
if claims[i].Affinity < minAffinity {
break
}
}
return claims[r.Intn(i)].ServerId, nil
}
if resErr != nil {
switch {
case opts.SelectionFunc != nil:
return opts.SelectionFunc(claims)
case serverID != "":
return serverID, nil
case resErr != nil:
return "", resErr
}
if len(claims) == 0 {
if resCount > 0 {
return "", psrpc.NewErrorf(psrpc.Unavailable, "no servers available (received %d responses)", resCount)
} else {
return "", psrpc.ErrNoResponse
}
case claimCount > 0:
return "", psrpc.NewErrorf(psrpc.Unavailable, "no servers available (received %d responses)", claimCount)
default:
return "", psrpc.ErrNoResponse
}
case claim := <-claimChan:
resCount++
claimCount++
if (opts.MinimumAffinity > 0 && claim.Affinity >= opts.MinimumAffinity) || opts.MinimumAffinity <= 0 {
if opts.AcceptFirstAvailable || opts.MaximumAffinity > 0 && claim.Affinity >= opts.MaximumAffinity {
return claim.ServerId, nil
}
claims = append(claims, claim)
if opts.SelectionFunc != nil {
claims = append(claims, &psrpc.Claim{ServerID: claim.ServerId, Affinity: claim.Affinity})
} else if claim.Affinity > affinity {
serverID = claim.ServerId
affinity = claim.Affinity
}
if opts.ShortCircuitTimeout > 0 && !shorted {
shorted = true
+11 -6
View File
@@ -29,12 +29,17 @@ type RequestOpts struct {
}
type SelectionOpts struct {
MinimumAffinity float32 // minimum affinity for a server to be considered a valid handler
MaximumAffinity float32 // if > 0, any server returning a max score will be selected immediately
Jitter float32 // randomness applied to selection (0 to 1)
AcceptFirstAvailable bool // go fast
AffinityTimeout time.Duration // server selection deadline
ShortCircuitTimeout time.Duration // deadline imposed after receiving first response
MinimumAffinity float32 // minimum affinity for a server to be considered a valid handler
MaximumAffinity float32 // if > 0, any server returning a max score will be selected immediately
AcceptFirstAvailable bool // go fast
AffinityTimeout time.Duration // server selection deadline
ShortCircuitTimeout time.Duration // deadline imposed after receiving first response
SelectionFunc func([]*Claim) (string, error) // custom server selection function
}
type Claim struct {
ServerID string
Affinity float32
}
func WithRequestTimeout(timeout time.Duration) RequestOption {