fn: freezer/evictor adjustments (#1233)

*) removed faulty Idle state setter in runHot() since with
UDS wait, we need to wait until we can determine if a container
is idle. This is now moved to runHotReq().
*) evictor now more aggresive and no longer tied to pause
timer/configuration.
*) removed unnecessary optimization on timer=0 case for immediate
pause.
This commit is contained in:
Tolga Ceylan
2018-09-20 14:13:11 -07:00
committed by GitHub
parent 0ed1fe8a11
commit a994b57d9a

View File

@@ -989,9 +989,6 @@ func (a *agent) runHot(ctx context.Context, call *call, tok ResourceToken, state
return return
} }
// container is running
state.UpdateState(ctx, ContainerStateIdle, call.slots)
// buffered, in case someone has slot when waiter returns but isn't yet listening // buffered, in case someone has slot when waiter returns but isn't yet listening
errC := make(chan error, 1) errC := make(chan error, 1)
@@ -1101,44 +1098,27 @@ func (a *agent) runHotReq(ctx context.Context, call *call, state ContainerState,
var err error var err error
isFrozen := false isFrozen := false
isEvictable := false isEvictEvent := false
freezeTimer := time.NewTimer(a.cfg.FreezeIdle) freezeTimer := time.NewTimer(a.cfg.FreezeIdle)
idleTimer := time.NewTimer(time.Duration(call.IdleTimeout) * time.Second) idleTimer := time.NewTimer(time.Duration(call.IdleTimeout) * time.Second)
evictor := a.evictor.GetEvictor(call.ID, call.slotHashId, call.Memory+uint64(call.TmpFsSize), uint64(call.CPUs))
defer freezeTimer.Stop()
defer idleTimer.Stop()
// log if any error is encountered
defer func() { defer func() {
a.evictor.UnregisterEvictor(evictor)
freezeTimer.Stop()
idleTimer.Stop()
// log if any error is encountered
if err != nil { if err != nil {
logger.WithError(err).Error("hot function failure") logger.WithError(err).Error("hot function failure")
} }
}() }()
evictor := a.evictor.GetEvictor(call.ID, call.slotHashId, call.Memory+uint64(call.TmpFsSize), uint64(call.CPUs)) a.evictor.RegisterEvictor(evictor)
state.UpdateState(ctx, ContainerStateIdle, call.slots)
// if an immediate freeze is requested, freeze first before enqueuing at all.
if a.cfg.FreezeIdle == time.Duration(0) && !isFrozen {
err = cookie.Freeze(ctx)
if err != nil {
return false
}
isFrozen = true
state.UpdateState(ctx, ContainerStatePaused, call.slots)
if !isEvictable {
isEvictable = true
a.evictor.RegisterEvictor(evictor)
}
}
if !isFrozen {
state.UpdateState(ctx, ContainerStateIdle, call.slots)
}
s := call.slots.queueSlot(slot) s := call.slots.queueSlot(slot)
isEvictEvent := false
for { for {
select { select {
case <-s.trigger: // slot already consumed case <-s.trigger: // slot already consumed
@@ -1153,10 +1133,6 @@ func (a *agent) runHotReq(ctx context.Context, call *call, state ContainerState,
} }
isFrozen = true isFrozen = true
state.UpdateState(ctx, ContainerStatePaused, call.slots) state.UpdateState(ctx, ContainerStatePaused, call.slots)
if !isEvictable {
isEvictable = true
a.evictor.RegisterEvictor(evictor)
}
} }
continue continue
case <-evictor.C: case <-evictor.C:
@@ -1166,9 +1142,7 @@ func (a *agent) runHotReq(ctx context.Context, call *call, state ContainerState,
break break
} }
if isEvictable { a.evictor.UnregisterEvictor(evictor)
a.evictor.UnregisterEvictor(evictor)
}
// if we can acquire token, that means we are here due to // if we can acquire token, that means we are here due to
// abort/shutdown/timeout, attempt to acquire and terminate, // abort/shutdown/timeout, attempt to acquire and terminate,