mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
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:
committed by
Tolga Ceylan
parent
2df6c8d349
commit
182db94fad
@@ -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
|
||||
|
||||
34
api/runnerpool/fake_placer.go
Normal file
34
api/runnerpool/fake_placer.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user