Feature/acksync response writer (#1267)

This implements a "detached" mechanism to get an ack from the runner
once it actually starts to run a function. In this scenario the response
returned back is just a 202 if we placed the function in a specific
time-frame. If we hit some errors or we fail to place the fn in time we
return back different errors.
This commit is contained in:
Andrea Rosa
2018-11-09 18:25:43 +00:00
committed by Tolga Ceylan
parent 2df6c8d349
commit 182db94fad
17 changed files with 453 additions and 58 deletions

View File

@@ -23,12 +23,15 @@ func NewCHPlacer(cfg *PlacerConfig) Placer {
}
}
func (p *chPlacer) GetPlacerConfig() PlacerConfig {
return p.cfg
}
// This borrows the CH placement algorithm from the original FNLB.
// Because we ask a runner to accept load (queuing on the LB rather than on the nodes), we don't use
// the LB_WAIT to drive placement decisions: runners only accept work if they have the capacity for it.
func (p *chPlacer) PlaceCall(rp RunnerPool, ctx context.Context, call RunnerCall) error {
state := NewPlacerTracker(ctx, &p.cfg)
func (p *chPlacer) PlaceCall(ctx context.Context, rp RunnerPool, call RunnerCall) error {
state := NewPlacerTracker(ctx, &p.cfg, call)
defer state.HandleDone()
key := call.Model().FnID

View File

@@ -0,0 +1,34 @@
package runnerpool
import (
"context"
"time"
)
type fakeDetachedPlacer struct {
cfg PlacerConfig
sleeptime time.Duration
}
func NewFakeDetachedPlacer(cfg *PlacerConfig, st time.Duration) Placer {
return &fakeDetachedPlacer{
cfg: *cfg,
sleeptime: st,
}
}
func (p *fakeDetachedPlacer) GetPlacerConfig() PlacerConfig {
return p.cfg
}
// PlaceCall for the fakeDetachedPlacer just sleeps for a period of time to let the placer context to time out.
// It returns the context exceeded error only if the placer context times out and the request context is still valid
func (p *fakeDetachedPlacer) PlaceCall(ctx context.Context, rp RunnerPool, call RunnerCall) error {
state := NewPlacerTracker(ctx, &p.cfg, call)
defer state.HandleDone()
time.Sleep(p.sleeptime)
if state.placerCtx.Err() != nil && state.requestCtx.Err() == nil {
return state.placerCtx.Err()
}
return nil
}

View File

@@ -23,9 +23,12 @@ func NewNaivePlacer(cfg *PlacerConfig) Placer {
}
}
func (sp *naivePlacer) PlaceCall(rp RunnerPool, ctx context.Context, call RunnerCall) error {
func (sp *naivePlacer) GetPlacerConfig() PlacerConfig {
return sp.cfg
}
state := NewPlacerTracker(ctx, &sp.cfg)
func (sp *naivePlacer) PlaceCall(ctx context.Context, rp RunnerPool, call RunnerCall) error {
state := NewPlacerTracker(ctx, &sp.cfg, call)
defer state.HandleDone()
var runnerPoolErr error

View File

@@ -11,11 +11,15 @@ type PlacerConfig struct {
// Maximum amount of time a placer can hold a request during runner attempts
PlacerTimeout time.Duration `json:"placer_timeout"`
// Maximum amount of time a placer can hold an ack sync request during runner attempts
DetachedPlacerTimeout time.Duration `json:"detached_placer_timeout"`
}
func NewPlacerConfig() PlacerConfig {
return PlacerConfig{
RetryAllDelay: 10 * time.Millisecond,
PlacerTimeout: 360 * time.Second,
RetryAllDelay: 10 * time.Millisecond,
PlacerTimeout: 360 * time.Second,
DetachedPlacerTimeout: 30 * time.Second,
}
}

View File

@@ -19,8 +19,14 @@ type placerTracker struct {
isPlaced bool
}
func NewPlacerTracker(requestCtx context.Context, cfg *PlacerConfig) *placerTracker {
ctx, cancel := context.WithTimeout(context.Background(), cfg.PlacerTimeout)
func NewPlacerTracker(requestCtx context.Context, cfg *PlacerConfig, call RunnerCall) *placerTracker {
timeout := cfg.PlacerTimeout
if call.Model().Type == models.TypeDetached {
timeout = cfg.DetachedPlacerTimeout
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
return &placerTracker{
cfg: cfg,
requestCtx: requestCtx,

View File

@@ -13,7 +13,8 @@ import (
// Placer implements a placement strategy for calls that are load-balanced
// across runners in a pool
type Placer interface {
PlaceCall(rp RunnerPool, ctx context.Context, call RunnerCall) error
PlaceCall(ctx context.Context, rp RunnerPool, call RunnerCall) error
GetPlacerConfig() PlacerConfig
}
// RunnerPool is the abstraction for getting an ordered list of runners to try for a call