From a9bba2c3a81547183513e2cf561f93f695930490 Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Tue, 18 Sep 2018 15:20:39 -0700 Subject: [PATCH] fn: remove eviction timer to simplify eviction logic (#1223) We tie container pausing with evictions, where if a container is paused, then it is also eligible for eviction. --- api/agent/agent.go | 21 +++++++++++---------- api/agent/config.go | 8 -------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/api/agent/agent.go b/api/agent/agent.go index f5c0c2c1f..76b7f3146 100644 --- a/api/agent/agent.go +++ b/api/agent/agent.go @@ -1058,11 +1058,9 @@ func (a *agent) runHotReq(ctx context.Context, call *call, state ContainerState, freezeTimer := time.NewTimer(a.cfg.FreezeIdle) idleTimer := time.NewTimer(time.Duration(call.IdleTimeout) * time.Second) - ejectTimer := time.NewTimer(a.cfg.EjectIdle) defer freezeTimer.Stop() defer idleTimer.Stop() - defer ejectTimer.Stop() // log if any error is encountered defer func() { @@ -1071,6 +1069,8 @@ func (a *agent) runHotReq(ctx context.Context, call *call, state ContainerState, } }() + evictor := a.evictor.GetEvictor(call.ID, call.slotHashId, call.Memory+uint64(call.TmpFsSize), uint64(call.CPUs)) + // if an immediate freeze is requested, freeze first before enqueuing at all. if a.cfg.FreezeIdle == time.Duration(0) && !isFrozen { err = cookie.Freeze(ctx) @@ -1079,10 +1079,12 @@ func (a *agent) runHotReq(ctx context.Context, call *call, state ContainerState, } isFrozen = true state.UpdateState(ctx, ContainerStatePaused, call.slots) + if !isEvictable { + isEvictable = true + a.evictor.RegisterEvictor(evictor) + } } - evictor := a.evictor.GetEvictor(call.ID, call.slotHashId, call.Memory+uint64(call.TmpFsSize), uint64(call.CPUs)) - if !isFrozen { state.UpdateState(ctx, ContainerStateIdle, call.slots) } @@ -1104,16 +1106,15 @@ func (a *agent) runHotReq(ctx context.Context, call *call, state ContainerState, } isFrozen = true state.UpdateState(ctx, ContainerStatePaused, call.slots) + if !isEvictable { + isEvictable = true + a.evictor.RegisterEvictor(evictor) + } } continue case <-evictor.C: - logger.Debug("attempting hot function eject") + logger.Debug("attempting hot function eviction") isEvictEvent = true - case <-ejectTimer.C: - // we've been idle too long, now we are ejectable - a.evictor.RegisterEvictor(evictor) - isEvictable = true - continue } break } diff --git a/api/agent/config.go b/api/agent/config.go index 37569d625..9b07f68e2 100644 --- a/api/agent/config.go +++ b/api/agent/config.go @@ -14,7 +14,6 @@ type Config struct { DockerNetworks string `json:"docker_networks"` DockerLoadFile string `json:"docker_load_file"` FreezeIdle time.Duration `json:"freeze_idle_msecs"` - EjectIdle time.Duration `json:"eject_idle_msecs"` HotPoll time.Duration `json:"hot_poll_msecs"` HotLauncherTimeout time.Duration `json:"hot_launcher_timeout_msecs"` AsyncChewPoll time.Duration `json:"async_chew_poll_msecs"` @@ -46,9 +45,6 @@ const ( EnvDockerLoadFile = "FN_DOCKER_LOAD_FILE" // EnvFreezeIdle is the delay between a container being last used and being frozen EnvFreezeIdle = "FN_FREEZE_IDLE_MSECS" - // EnvEjectIdle is the delay before allowing an idle container to be evictable if another container - // requests the space for itself - EnvEjectIdle = "FN_EJECT_IDLE_MSECS" // EnvHotPoll is the interval to ping for a slot manager thread to check if a container should be // launched for a given function EnvHotPoll = "FN_HOT_POLL_MSECS" @@ -127,7 +123,6 @@ func NewConfig() (*Config, error) { var err error err = setEnvMsecs(err, EnvFreezeIdle, &cfg.FreezeIdle, 50*time.Millisecond) - err = setEnvMsecs(err, EnvEjectIdle, &cfg.EjectIdle, 1000*time.Millisecond) err = setEnvMsecs(err, EnvHotPoll, &cfg.HotPoll, DefaultHotPoll) err = setEnvMsecs(err, EnvHotLauncherTimeout, &cfg.HotLauncherTimeout, time.Duration(60)*time.Minute) err = setEnvMsecs(err, EnvAsyncChewPoll, &cfg.AsyncChewPoll, time.Duration(60)*time.Second) @@ -156,9 +151,6 @@ func NewConfig() (*Config, error) { return cfg, err } - if cfg.EjectIdle == time.Duration(0) { - return cfg, fmt.Errorf("error %s cannot be zero", EnvEjectIdle) - } if cfg.MaxLogSize > math.MaxInt64 { // for safety during uint64 to int conversions in Write()/Read(), etc. return cfg, fmt.Errorf("error invalid %s %v > %v", EnvMaxLogSize, cfg.MaxLogSize, math.MaxInt64)