lambda/interop/sandbox_model.go (165 lines of code) (raw):

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package interop import ( "bytes" "io" "net/http" "time" "go.amzn.com/lambda/fatalerror" "go.amzn.com/lambda/rapidcore/env" ) // Init represents an init message // In Rapid Shim, this is a START GirD message // In Rapid Daemon, this is an INIT GirP message type Init struct { InvokeID string Handler string AccountID string AwsKey string AwsSecret string AwsSession string CredentialsExpiry time.Time SuppressInit bool InvokeTimeoutMs int64 // timeout duration of whole invoke InitTimeoutMs int64 // timeout duration for init only XRayDaemonAddress string // only in standalone FunctionName string // only in standalone FunctionVersion string // only in standalone // In standalone mode, these env vars come from test/init but from environment otherwise. CustomerEnvironmentVariables map[string]string SandboxType SandboxType LogStreamName string InstanceMaxMemory uint64 OperatorDomainExtraConfig DynamicDomainConfig RuntimeDomainExtraConfig DynamicDomainConfig RuntimeInfo RuntimeInfo Bootstrap Bootstrap EnvironmentVariables *env.Environment // contains env vars for agents and runtime procs } // InitSuccess indicates that runtime/extensions initialization completed successfully // In Rapid Shim, this translates to a DONE GirD message to Slicer // In Rapid Daemon, this is followed by a DONEDONE GirP message to MM type InitSuccess struct { NumActiveExtensions int // indicates number of active extensions ExtensionNames string // file names of extensions in /opt/extensions RuntimeRelease string LogsAPIMetrics TelemetrySubscriptionMetrics // used if telemetry API enabled Ack chan struct{} // used by the sending goroutine to wait until ipc message has been sent } // InitFailure indicates that runtime/extensions initialization failed due to process exit or /error calls // In Rapid Shim, this translates to either a DONE or a DONEFAIL GirD message to Slicer (depending on extensions mode) // However, even on failure, the next invoke is expected to work with a suppressed init - i.e. we init again as aprt of the invoke type InitFailure struct { ResetReceived bool // indicates if failure happened due to a reset received RequestReset bool // Indicates whether reset should be requested on init failure ErrorType fatalerror.ErrorType ErrorMessage error NumActiveExtensions int RuntimeRelease string // value of the User Agent HTTP header provided by runtime LogsAPIMetrics TelemetrySubscriptionMetrics Ack chan struct{} // used by the sending goroutine to wait until ipc message has been sent } // ErrorInvokeResponse represents a buffered response received via Runtime API // for error responses. When body (Payload) is not provided, e.g. // not retrievable, error type and error message headers will be // used by the platform to construct a response json, e.g: // // default error response produced by the Slicer: // '{"errorMessage":"Unknown application error occurred"}', // // when error type is provided, error response becomes: // '{"errorMessage":"Unknown application error occurred","errorType":"ErrorType"}' type ErrorInvokeResponse struct { Headers InvokeResponseHeaders Payload []byte FunctionError FunctionError } // StreamableInvokeResponse represents a response received via Runtime API that can be streamed type StreamableInvokeResponse struct { Headers map[string]string Payload io.Reader Trailers http.Header Request *CancellableRequest // streaming request may need to gracefully terminate request streams } // InvokeResponseHeaders contains the headers received via Runtime API /invocation/response type InvokeResponseHeaders struct { ContentType string FunctionResponseMode string } // FunctionError represents information about function errors or 'user errors' // These are not platform errors and hence are returned as 200 by Lambda // In the absence of a response payload, the Function Error is serialized and sent type FunctionError struct { // Type of error is derived from the Lambda-Runtime-Function-Error-Type set by the Runtime // This is customer data, so RAPID scrubs this error type to contain only allowlisted values Type fatalerror.ErrorType `json:"errorType,omitempty"` // ErrorMessage is generated by RAPID and can never be specified by runtime Message string `json:"errorMessage,omitempty"` } type InvokeResponseSender interface { // SendResponse sends invocation response received from Runtime to platform // This is response may be streamed based on function and invoke response mode SendResponse(invokeID string, response *StreamableInvokeResponse) error // SendErrorResponse sends error response in the case of function errors, which are always buffered SendErrorResponse(invokeID string, response *ErrorInvokeResponse) error } // ResponseMetrics groups metrics related to the response stream type ResponseMetrics struct { RuntimeOutboundThroughputBps int64 RuntimeProducedBytes int64 RuntimeResponseLatencyMs float64 RuntimeTimeThrottledMs int64 } // InvokeMetrics groups metrics related to the invoke phase type InvokeMetrics struct { InvokeRequestReadTimeNs int64 InvokeRequestSizeBytes int64 RuntimeReadyTime int64 } // InvokeSuccess is the success response to invoke phase end type InvokeSuccess struct { RuntimeRelease string // value of the User Agent HTTP header provided by runtime NumActiveExtensions int ExtensionNames string InvokeCompletionTimeNs int64 InvokeReceivedTime int64 LogsAPIMetrics TelemetrySubscriptionMetrics ResponseMetrics ResponseMetrics InvokeMetrics InvokeMetrics InvokeResponseMode InvokeResponseMode } // InvokeFailure is the failure response to invoke phase end type InvokeFailure struct { ResetReceived bool // indicates if failure happened due to a reset received RequestReset bool // indicates if reset must be requested after the failure ErrorType fatalerror.ErrorType ErrorMessage error RuntimeRelease string // value of the User Agent HTTP header provided by runtime NumActiveExtensions int InvokeReceivedTime int64 LogsAPIMetrics TelemetrySubscriptionMetrics ResponseMetrics ResponseMetrics InvokeMetrics InvokeMetrics ExtensionNames string DefaultErrorResponse *ErrorInvokeResponse // error resp constructed by platform during fn errors InvokeResponseMode InvokeResponseMode } // ResetSuccess is the success response to reset request type ResetSuccess struct { ExtensionsResetMs int64 ErrorType fatalerror.ErrorType ResponseMetrics ResponseMetrics InvokeResponseMode InvokeResponseMode } // ResetFailure is the failure response to reset request type ResetFailure struct { ExtensionsResetMs int64 ErrorType fatalerror.ErrorType ResponseMetrics ResponseMetrics InvokeResponseMode InvokeResponseMode } // ShutdownSuccess is the response to a shutdown request type ShutdownSuccess struct { ErrorType fatalerror.ErrorType } // SandboxInfoFromInit captures data from init request that // is required during invoke (e.g. for suppressed init) type SandboxInfoFromInit struct { EnvironmentVariables *env.Environment // contains agent env vars (creds, customer, platform) SandboxType SandboxType // indicating Pre-Warmed, On-Demand etc RuntimeBootstrap Bootstrap // contains the runtime bootstrap binary path, Cwd, Args, Env, Cmd } // RestoreResult represents the result of `HandleRestore` function // in RapidCore type RestoreResult struct { RestoreMs int64 } // RapidContext expose methods for functionality of the Rapid Core library type RapidContext interface { HandleInit(i *Init, success chan<- InitSuccess, failure chan<- InitFailure) HandleInvoke(i *Invoke, sbMetadata SandboxInfoFromInit, requestBuf *bytes.Buffer, responseSender InvokeResponseSender) (InvokeSuccess, *InvokeFailure) HandleReset(reset *Reset) (ResetSuccess, *ResetFailure) HandleShutdown(shutdown *Shutdown) ShutdownSuccess HandleRestore(restore *Restore) (RestoreResult, error) Clear() SetRuntimeStartedTime(runtimeStartedTime int64) SetInvokeResponseMetrics(metrics *InvokeResponseMetrics) SetEventsAPI(eventsAPI EventsAPI) } // SandboxContext represents the sandbox lifecycle context type SandboxContext interface { Init(i *Init, timeoutMs int64) InitContext Reset(reset *Reset) (ResetSuccess, *ResetFailure) Shutdown(shutdown *Shutdown) ShutdownSuccess Restore(restore *Restore) (RestoreResult, error) // TODO: refactor this // runtimeStartedTime and InvokeResponseMetrics are needed to compute the runtimeDone metrics // in case of a Reset during an invoke (reset.reason=failure or reset.reason=timeout). // Ideally: // - the InvokeContext will have a Reset method to deal with Reset during an invoke and will hold runtimeStartedTime and InvokeResponseMetrics // - the SandboxContext will have its own Reset/Spindown method SetRuntimeStartedTime(invokeReceivedTime int64) SetInvokeResponseMetrics(metrics *InvokeResponseMetrics) } // InitContext represents the lifecycle of a sandbox initialization type InitContext interface { Wait() (InitSuccess, *InitFailure) Reserve() InvokeContext } // InvokeContext represents the lifecycle of a sandbox reservation type InvokeContext interface { SendRequest(i *Invoke, r InvokeResponseSender) Wait() (InvokeSuccess, *InvokeFailure) } // LifecyclePhase represents enum for possible Sandbox lifecycle phases, like init, invoke, etc. type LifecyclePhase int const ( LifecyclePhaseInit LifecyclePhase = iota + 1 LifecyclePhaseInvoke )