mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: LB ch and naive fixes (#942)
* fn: LB ch and naive fixes *) Naive is now a naive RR algorithm. *) Both now checks for ctx/timeout in each attempt. * fn: test fix
This commit is contained in:
committed by
Reed Allman
parent
878524ea6c
commit
f0f9a6d945
@@ -30,46 +30,47 @@ func (p *chPlacer) PlaceCall(rp RunnerPool, ctx context.Context, call RunnerCall
|
||||
sum64 := siphash.Hash(0, 0x4c617279426f6174, []byte(key))
|
||||
timeout := time.After(call.LbDeadline().Sub(time.Now()))
|
||||
for {
|
||||
runners, err := rp.Runners(call)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to find runners for call")
|
||||
} else {
|
||||
i := int(jumpConsistentHash(sum64, int32(len(runners))))
|
||||
for j := 0; j < len(runners); j++ {
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
case <-timeout:
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
default:
|
||||
}
|
||||
|
||||
r := runners[i]
|
||||
|
||||
placed, err := r.TryExec(ctx, call)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed during call placement")
|
||||
}
|
||||
if placed {
|
||||
return err
|
||||
}
|
||||
|
||||
i = (i + 1) % len(runners)
|
||||
}
|
||||
}
|
||||
|
||||
remaining := call.LbDeadline().Sub(time.Now())
|
||||
if remaining <= 0 {
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
}
|
||||
|
||||
// backoff
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
case <-timeout:
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
default:
|
||||
runners, err := rp.Runners(call)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to find runners for call")
|
||||
} else {
|
||||
i := int(jumpConsistentHash(sum64, int32(len(runners))))
|
||||
for j := 0; j < len(runners); j++ {
|
||||
r := runners[i]
|
||||
|
||||
placed, err := r.TryExec(ctx, call)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed during call placement")
|
||||
}
|
||||
if placed {
|
||||
return err
|
||||
}
|
||||
|
||||
i = (i + 1) % len(runners)
|
||||
}
|
||||
}
|
||||
|
||||
remaining := call.LbDeadline().Sub(time.Now())
|
||||
if remaining <= 0 {
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
}
|
||||
|
||||
// backoff
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
case <-timeout:
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
case <-time.After(common.MinDuration(retryWaitInterval, remaining)):
|
||||
}
|
||||
case <-time.After(common.MinDuration(retryWaitInterval, remaining)):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package runnerpool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/fnproject/fn/api/common"
|
||||
@@ -15,51 +16,61 @@ const (
|
||||
retryWaitInterval = 10 * time.Millisecond
|
||||
)
|
||||
|
||||
type naivePlacer struct{}
|
||||
type naivePlacer struct {
|
||||
rrIndex uint64
|
||||
}
|
||||
|
||||
func NewNaivePlacer() Placer {
|
||||
logrus.Info("Creating new naive runnerpool placer")
|
||||
return &naivePlacer{}
|
||||
rrIndex := uint64(time.Now().Nanosecond())
|
||||
logrus.Infof("Creating new naive runnerpool placer rrIndex=%d", rrIndex)
|
||||
return &naivePlacer{
|
||||
rrIndex: rrIndex,
|
||||
}
|
||||
}
|
||||
|
||||
func (sp *naivePlacer) PlaceCall(rp RunnerPool, ctx context.Context, call RunnerCall) error {
|
||||
timeout := time.After(call.LbDeadline().Sub(time.Now()))
|
||||
|
||||
for {
|
||||
runners, err := rp.Runners(call)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to find runners for call")
|
||||
} else {
|
||||
for j := 0; j < len(runners); j++ {
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
case <-timeout:
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
default:
|
||||
}
|
||||
|
||||
i := atomic.AddUint64(&sp.rrIndex, uint64(1))
|
||||
r := runners[int(i)%len(runners)]
|
||||
|
||||
placed, err := r.TryExec(ctx, call)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed during call placement")
|
||||
}
|
||||
if placed {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remaining := call.LbDeadline().Sub(time.Now())
|
||||
if remaining <= 0 {
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
}
|
||||
|
||||
// backoff
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
case <-timeout:
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
default:
|
||||
runners, err := rp.Runners(call)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to find runners for call")
|
||||
} else {
|
||||
for _, r := range runners {
|
||||
placed, err := r.TryExec(ctx, call)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed during call placement")
|
||||
}
|
||||
if placed {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remaining := call.LbDeadline().Sub(time.Now())
|
||||
if remaining <= 0 {
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
}
|
||||
|
||||
// backoff
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
case <-timeout:
|
||||
return models.ErrCallTimeoutServerBusy
|
||||
case <-time.After(common.MinDuration(retryWaitInterval, remaining)):
|
||||
}
|
||||
case <-time.After(common.MinDuration(retryWaitInterval, remaining)):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user