mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: agent slot improvements (#704)
*) Stopped using latency previous/current stats, this was not working as expected. Fresh starts usually have these stats zero for a long time, and initial samples are high due to downloads, caches, etc. *) New state to track: containers that are idle. In other words, containers that have an unused token in the slot queue. *) Removed latency counts since these are not used in container start decision anymore. Simplifies logs. *) isNewContainerNeeded() simplified to use idle count to estimate effective waiters. Removed speculative latency based logic and progress check comparison. In agent, waitHot() delayed signalling compansates for these changes. If the estimation may fail, but this should correct itself in the next 200 msec signal.
This commit is contained in:
@@ -319,7 +319,6 @@ func (a *agent) hotLauncher(ctx context.Context, callObj *call) {
|
||||
logger := common.Logger(ctx)
|
||||
logger.WithField("launcher_timeout", timeout).Info("Hot function launcher starting")
|
||||
isAsync := callObj.Type == models.TypeAsync
|
||||
prevStats := callObj.slots.getStats()
|
||||
|
||||
for {
|
||||
select {
|
||||
@@ -334,11 +333,10 @@ func (a *agent) hotLauncher(ctx context.Context, callObj *call) {
|
||||
}
|
||||
|
||||
curStats := callObj.slots.getStats()
|
||||
isNeeded := isNewContainerNeeded(&curStats, &prevStats)
|
||||
prevStats = curStats
|
||||
isNeeded := isNewContainerNeeded(&curStats)
|
||||
logger.WithFields(logrus.Fields{
|
||||
"currentStats": curStats,
|
||||
"previousStats": curStats,
|
||||
"currentStats": curStats,
|
||||
"isNeeded": isNeeded,
|
||||
}).Debug("Hot function launcher stats")
|
||||
if !isNeeded {
|
||||
continue
|
||||
@@ -346,8 +344,8 @@ func (a *agent) hotLauncher(ctx context.Context, callObj *call) {
|
||||
|
||||
ctxResource, cancelResource := context.WithCancel(context.Background())
|
||||
logger.WithFields(logrus.Fields{
|
||||
"currentStats": curStats,
|
||||
"previousStats": curStats,
|
||||
"currentStats": curStats,
|
||||
"isNeeded": isNeeded,
|
||||
}).Info("Hot function launcher starting hot container")
|
||||
|
||||
select {
|
||||
@@ -673,22 +671,28 @@ func (a *agent) runHot(ctxArg context.Context, call *call, tok ResourceToken) {
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
start := time.Now()
|
||||
call.slots.enterState(SlotQueueIdle)
|
||||
s := call.slots.queueSlot(&hotSlot{done, proto, errC, container, nil})
|
||||
|
||||
select {
|
||||
case <-s.trigger:
|
||||
call.slots.exitStateWithLatency(SlotQueueIdle, uint64(time.Now().Sub(start).Seconds()*1000))
|
||||
case <-time.After(time.Duration(call.IdleTimeout) * time.Second):
|
||||
if call.slots.ejectSlot(s) {
|
||||
call.slots.exitStateWithLatency(SlotQueueIdle, uint64(time.Now().Sub(start).Seconds()*1000))
|
||||
logger.Info("Canceling inactive hot function")
|
||||
shutdownContainer()
|
||||
return
|
||||
}
|
||||
case <-ctx.Done(): // container shutdown
|
||||
if call.slots.ejectSlot(s) {
|
||||
call.slots.exitStateWithLatency(SlotQueueIdle, uint64(time.Now().Sub(start).Seconds()*1000))
|
||||
return
|
||||
}
|
||||
case <-a.shutdown: // server shutdown
|
||||
if call.slots.ejectSlot(s) {
|
||||
call.slots.exitStateWithLatency(SlotQueueIdle, uint64(time.Now().Sub(start).Seconds()*1000))
|
||||
shutdownContainer()
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user