mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: resource and slot cancel and broadcast improvements (#696)
* fn: resource and slot cancel and broadcast improvements *) Context argument does not wake up the waiters correctly upon cancellation/timeout. *) Avoid unnecessary broadcasts in slot and resource. * fn: limit scope of context in resource/slot calls in agent
This commit is contained in:
@@ -344,15 +344,15 @@ func (a *agent) hotLauncher(ctx context.Context, callObj *call) {
|
||||
continue
|
||||
}
|
||||
|
||||
resourceCtx, cancel := context.WithCancel(context.Background())
|
||||
ctxResource, cancelResource := context.WithCancel(context.Background())
|
||||
logger.WithFields(logrus.Fields{
|
||||
"currentStats": curStats,
|
||||
"previousStats": curStats,
|
||||
}).Info("Hot function launcher starting hot container")
|
||||
|
||||
select {
|
||||
case tok, isOpen := <-a.resources.GetResourceToken(resourceCtx, callObj.Memory, uint64(callObj.CPUs), isAsync):
|
||||
cancel()
|
||||
case tok, isOpen := <-a.resources.GetResourceToken(ctxResource, callObj.Memory, uint64(callObj.CPUs), isAsync):
|
||||
cancelResource()
|
||||
if isOpen {
|
||||
a.wg.Add(1)
|
||||
go func(ctx context.Context, call *call, tok ResourceToken) {
|
||||
@@ -364,13 +364,13 @@ func (a *agent) hotLauncher(ctx context.Context, callObj *call) {
|
||||
callObj.slots.queueSlot(&hotSlot{done: make(chan struct{}), err: models.ErrCallTimeoutServerBusy})
|
||||
}
|
||||
case <-time.After(timeout):
|
||||
cancel()
|
||||
cancelResource()
|
||||
if a.slotMgr.deleteSlotQueue(callObj.slots) {
|
||||
logger.Info("Hot function launcher timed out")
|
||||
return
|
||||
}
|
||||
case <-a.shutdown: // server shutdown
|
||||
cancel()
|
||||
cancelResource()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -378,8 +378,10 @@ func (a *agent) hotLauncher(ctx context.Context, callObj *call) {
|
||||
|
||||
// waitHot pings and waits for a hot container from the slot queue
|
||||
func (a *agent) waitHot(ctx context.Context, call *call) (Slot, error) {
|
||||
ch, cancel := call.slots.startDequeuer()
|
||||
defer cancel()
|
||||
|
||||
ctxDequeuer, cancelDequeuer := context.WithCancel(ctx)
|
||||
defer cancelDequeuer()
|
||||
ch := call.slots.startDequeuer(ctxDequeuer)
|
||||
|
||||
// 1) if we can get a slot immediately, grab it.
|
||||
// 2) if we don't, send a signaller every 200ms until we do.
|
||||
@@ -420,9 +422,11 @@ func (a *agent) launchCold(ctx context.Context, call *call) (Slot, error) {
|
||||
|
||||
isAsync := call.Type == models.TypeAsync
|
||||
ch := make(chan Slot)
|
||||
ctxResource, cancelResource := context.WithCancel(ctx)
|
||||
defer cancelResource()
|
||||
|
||||
select {
|
||||
case tok, isOpen := <-a.resources.GetResourceToken(ctx, call.Memory, uint64(call.CPUs), isAsync):
|
||||
case tok, isOpen := <-a.resources.GetResourceToken(ctxResource, call.Memory, uint64(call.CPUs), isAsync):
|
||||
if !isOpen {
|
||||
return nil, models.ErrCallTimeoutServerBusy
|
||||
}
|
||||
@@ -431,6 +435,8 @@ func (a *agent) launchCold(ctx context.Context, call *call) (Slot, error) {
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
|
||||
cancelResource()
|
||||
|
||||
// wait for launch err or a slot to open up
|
||||
select {
|
||||
case s := <-ch:
|
||||
|
||||
Reference in New Issue
Block a user