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.
This commit is contained in:
Tolga Ceylan
2018-09-18 15:20:39 -07:00
committed by GitHub
parent b043e619d3
commit a9bba2c3a8
2 changed files with 11 additions and 18 deletions

View File

@@ -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
}

View File

@@ -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)