func handleReset()

in lambda/rapid/handlers.go [709:784]


func handleReset(execCtx *rapidContext, resetEvent *interop.Reset, runtimeStartedTime int64, invokeResponseMetrics *interop.InvokeResponseMetrics) (interop.ResetSuccess, *interop.ResetFailure) {
	log.Warnf("Reset initiated: %s", resetEvent.Reason)

	// Only send RuntimeDone event if we get a reset during an Invoke
	if resetEvent.Reason == "failure" || resetEvent.Reason == "timeout" {
		var errorType *string
		if resetEvent.Reason == "failure" {
			firstFatalError, found := appctx.LoadFirstFatalError(execCtx.appCtx)
			if !found {
				firstFatalError = fatalerror.SandboxFailure
			}
			stringifiedError := string(firstFatalError)
			errorType = &stringifiedError
		}

		var status string
		if resetEvent.Reason == "timeout" {
			status = "timeout"
		} else if strings.HasPrefix(*errorType, "Sandbox.") {
			status = "failure"
		} else {
			status = "error"
		}

		var runtimeReadyTime int64 = metering.Monotime()
		runtimeDoneEventData := interop.InvokeRuntimeDoneData{
			Status:          status,
			InternalMetrics: invokeResponseMetrics,
			Metrics:         telemetry.GetRuntimeDoneInvokeMetrics(runtimeStartedTime, invokeResponseMetrics, runtimeReadyTime),
			Tracing:         execCtx.xray.BuildTracingCtxAfterInvokeComplete(),
			Spans:           execCtx.eventsAPI.GetRuntimeDoneSpans(runtimeStartedTime, invokeResponseMetrics, execCtx.RuntimeOverheadStartedTime, runtimeReadyTime),
			ErrorType:       errorType,
		}
		if err := execCtx.eventsAPI.SendInvokeRuntimeDone(runtimeDoneEventData); err != nil {
			log.Errorf("Failed to send INVOKE RTDONE: %s", err)
		}
	}

	extensionsResetMs, resetTimeout, _ := execCtx.shutdownContext.shutdown(execCtx, resetEvent.DeadlineNs, resetEvent.Reason)

	execCtx.runtimeDomainGeneration++

	// Only used by standalone for more indepth assertions.
	var fatalErrorType fatalerror.ErrorType

	if execCtx.standaloneMode {
		fatalErrorType, _ = appctx.LoadFirstFatalError(execCtx.appCtx)
	}

	// TODO: move interop.ResponseMetrics{} to a factory method and initialize it there.
	// Initialization is very similar in handleInvoke's invokeFailure.ResponseMetrics and
	// invokeSuccessMsg.ResponseMetrics
	var responseMetrics interop.ResponseMetrics
	if resetEvent.InvokeResponseMetrics != nil && interop.IsResponseStreamingMetrics(resetEvent.InvokeResponseMetrics) {
		responseMetrics.RuntimeResponseLatencyMs = telemetry.CalculateDuration(execCtx.RuntimeStartedTime, resetEvent.InvokeResponseMetrics.StartReadingResponseMonoTimeMs)
		responseMetrics.RuntimeTimeThrottledMs = resetEvent.InvokeResponseMetrics.TimeShapedNs / int64(time.Millisecond)
		responseMetrics.RuntimeProducedBytes = resetEvent.InvokeResponseMetrics.ProducedBytes
		responseMetrics.RuntimeOutboundThroughputBps = resetEvent.InvokeResponseMetrics.OutboundThroughputBps
	}

	if resetTimeout {
		return interop.ResetSuccess{}, &interop.ResetFailure{
			ExtensionsResetMs:  extensionsResetMs,
			ErrorType:          fatalErrorType,
			ResponseMetrics:    responseMetrics,
			InvokeResponseMode: resetEvent.InvokeResponseMode,
		}
	}

	return interop.ResetSuccess{
		ExtensionsResetMs:  extensionsResetMs,
		ErrorType:          fatalErrorType,
		ResponseMetrics:    responseMetrics,
		InvokeResponseMode: resetEvent.InvokeResponseMode,
	}, nil
}