Files
fn-serverless/api/runnerpool/naive_placer.go
Tolga Ceylan a57907eed0 fn: user friendly timeout handling changes (#1021)
* fn: user friendly timeout handling changes

Timeout setting in routes now means "maximum amount
of time a function can run in a container".

Total wait time for a given http request is now expected
to be handled by the client. As long as the client waits,
the LB, runner or agents will search for resources to
schedule it.
2018-06-01 13:18:13 -07:00

66 lines
1.3 KiB
Go

package runnerpool
import (
"context"
"sync/atomic"
"time"
"github.com/fnproject/fn/api/models"
"github.com/sirupsen/logrus"
)
type naivePlacer struct {
rrInterval time.Duration
rrIndex uint64
}
func NewNaivePlacer() Placer {
rrIndex := uint64(time.Now().Nanosecond())
logrus.Infof("Creating new naive runnerpool placer rrIndex=%d", rrIndex)
return &naivePlacer{
rrInterval: 10 * time.Millisecond,
rrIndex: rrIndex,
}
}
func (sp *naivePlacer) PlaceCall(rp RunnerPool, ctx context.Context, call RunnerCall) error {
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
default:
}
i := atomic.AddUint64(&sp.rrIndex, uint64(1))
r := runners[int(i)%len(runners)]
tryCtx, tryCancel := context.WithCancel(ctx)
placed, err := r.TryExec(tryCtx, call)
tryCancel()
if err != nil {
logrus.WithError(err).Error("Failed during call placement")
}
if placed {
return err
}
}
}
// backoff
select {
case <-ctx.Done():
return models.ErrCallTimeoutServerBusy
case <-time.After(sp.rrInterval):
}
}
}