in lambda/rapid/shutdown.go [305:368]
func (s *shutdownContext) shutdown(execCtx *rapidContext, deadlineNs int64, reason string) (int64, bool, error) {
var err error
s.setShuttingDown(true)
defer s.setShuttingDown(false)
// Fatal errors such as Runtime exit and Extension.Crash
// are ignored by the events watcher when shutting down
execCtx.appCtx.Delete(appctx.AppCtxFirstFatalErrorKey)
runtimeDomainProfiler := &metering.ExtensionsResetDurationProfiler{}
// We do not spend any compute time on runtime graceful shutdown if there are no agents
if execCtx.registrationService.CountAgents() == 0 {
name := fmt.Sprintf("%s-%d", runtimeProcessName, execCtx.runtimeDomainGeneration)
_, found := s.getExitedChannel(name)
if found {
log.Debug("SIGKILLing the runtime as no agents are registered.")
err = execCtx.supervisor.Kill(context.Background(), &supvmodel.KillRequest{
Domain: RuntimeDomain,
Name: name,
Deadline: time.Now().Add(time.Millisecond * supervisorBlockingMaxMillis),
})
if err != nil {
// We are not reporting the error upstream because we will anyway
// shut the domain out at the end of the shutdown sequence
log.WithError(err).Warn("Failed sending Kill signal to runtime")
}
} else {
log.Debugf("Could not find runtime process %s in processes map. Already exited/never started", name)
}
} else {
mono := metering.Monotime()
availableNs := deadlineNs - mono
if availableNs < 0 {
log.Warnf("Deadline is in the past: %v, %v, %v", mono, deadlineNs, availableNs)
availableNs = 0
}
start := time.Now()
runtimeDeadline := start.Add(time.Duration(float64(availableNs) * runtimeDeadlineShare))
agentsDeadline := start.Add(time.Duration(availableNs))
runtimeDomainProfiler.AvailableNs = availableNs
runtimeDomainProfiler.Start()
s.shutdownRuntime(execCtx, start, runtimeDeadline)
s.shutdownAgents(execCtx, start, agentsDeadline, reason)
runtimeDomainProfiler.NumAgentsRegisteredForShutdown = len(s.agentsAwaitingExit)
}
log.Info("Waiting for runtime domain processes termination")
if err := s.clearExitedChannel(); err != nil {
log.Error(err)
}
runtimeDomainProfiler.Stop()
extensionsResetMs, timeout := runtimeDomainProfiler.CalculateExtensionsResetMs()
return extensionsResetMs, timeout, err
}