Skip to content

Commit f19914e

Browse files
Add invocation timeout handling (#6)
Co-authored-by: Dominik Schubert <[email protected]>
1 parent d5b8859 commit f19914e

File tree

3 files changed

+42
-11
lines changed

3 files changed

+42
-11
lines changed

Diff for: Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# LOCALSTACK CHANGES 2022-03-10: remove linker flags and add gc flags for delve debugger
22
# LOCALSTACK CHANGES 2022-03-28: change compile src folder
3+
# LOCALSTACK CHANGES 2022-11-14: add --rm flag to compile-with-docker
34

45
# RELEASE_BUILD_LINKER_FLAGS disables DWARF and symbol table generation to reduce binary size
56
#RELEASE_BUILD_LINKER_FLAGS=-s -w
@@ -21,7 +22,7 @@ compile-lambda-linux-all:
2122
make ARCH=arm64 compile-lambda-linux
2223

2324
compile-with-docker:
24-
docker run --env GOPROXY=direct -v $(shell pwd):/LambdaRuntimeLocal -w /LambdaRuntimeLocal golang:1.18 make ARCH=${ARCH} compile-lambda-linux
25+
docker run --rm --env GOPROXY=direct -v $(shell pwd):/LambdaRuntimeLocal -w /LambdaRuntimeLocal golang:1.18 make ARCH=${ARCH} compile-lambda-linux
2526

2627
compile-lambda-linux:
2728
CGO_ENABLED=0 GOOS=linux GOARCH=${GO_ARCH_${ARCH}} go build -ldflags "${RELEASE_BUILD_LINKER_FLAGS}" -gcflags="all=-N -l" -o ${DESTINATION_${ARCH}} ./cmd/localstack

Diff for: cmd/localstack/custom_interop.go

+31-8
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ type InvokeRequest struct {
5252

5353
type ErrorResponse struct {
5454
ErrorMessage string `json:"errorMessage"`
55-
ErrorType string `json:"errorType"`
56-
RequestId string `json:"requestId"`
57-
StackTrace []string `json:"stackTrace"`
55+
ErrorType string `json:"errorType,omitempty"`
56+
RequestId string `json:"requestId,omitempty"`
57+
StackTrace []string `json:"stackTrace,omitempty"`
5858
}
5959

6060
func NewCustomInteropServer(lsOpts *LsOpts, delegate rapidcore.InteropServer, logCollector *LogCollector) (server *CustomInteropServer) {
@@ -99,12 +99,36 @@ func NewCustomInteropServer(lsOpts *LsOpts, delegate rapidcore.InteropServer, lo
9999
CorrelationID: "invokeCorrelationID",
100100
NeedDebugLogs: true,
101101
InvokedFunctionArn: invokeR.InvokedFunctionArn,
102+
//DeadlineNs:
102103
})
104+
timeout := int(server.delegate.GetInvokeTimeout().Seconds())
105+
isErr := false
103106
if err != nil {
104-
log.Fatalln(err)
107+
switch err {
108+
case rapidcore.ErrInvokeTimeout:
109+
log.Debugf("Got invoke timeout")
110+
isErr = true
111+
errorResponse := ErrorResponse{
112+
ErrorMessage: fmt.Sprintf(
113+
"%s %s Task timed out after %d.00 seconds",
114+
time.Now().Format("2006-01-02T15:04:05Z"),
115+
invokeR.InvokeId,
116+
timeout,
117+
),
118+
}
119+
jsonErrorResponse, err := json.Marshal(errorResponse)
120+
if err != nil {
121+
log.Fatalln("unable to marshall json timeout response")
122+
}
123+
_, err = invokeResp.Write(jsonErrorResponse)
124+
if err != nil {
125+
log.Fatalln("unable to write to response")
126+
}
127+
default:
128+
log.Fatalln(err)
129+
}
105130
}
106-
inv := GetEnvOrDie("AWS_LAMBDA_FUNCTION_TIMEOUT")
107-
timeoutDuration, _ := time.ParseDuration(inv + "s")
131+
timeoutDuration := time.Duration(timeout) * time.Second
108132
memorySize := GetEnvOrDie("AWS_LAMBDA_FUNCTION_MEMORY_SIZE")
109133
PrintEndReports(invokeR.InvokeId, "", memorySize, invokeStart, timeoutDuration, logCollector)
110134

@@ -117,8 +141,7 @@ func NewCustomInteropServer(lsOpts *LsOpts, delegate rapidcore.InteropServer, lo
117141
var errR map[string]any
118142
marshalErr := json.Unmarshal(invokeResp.Body, &errR)
119143

120-
isErr := false
121-
if marshalErr == nil {
144+
if !isErr && marshalErr == nil {
122145
_, isErr = errR["errorType"]
123146
}
124147

Diff for: cmd/localstack/main.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
_ "net/http/pprof"
1010
"os"
1111
"runtime/debug"
12+
"strconv"
1213
)
1314

1415
type LsOpts struct {
@@ -72,12 +73,18 @@ func main() {
7273
// initialize all flows and start runtime API
7374
go sandbox.Create()
7475

76+
// get timeout
77+
invokeTimeoutEnv := GetEnvOrDie("AWS_LAMBDA_FUNCTION_TIMEOUT")
78+
invokeTimeoutSeconds, err := strconv.Atoi(invokeTimeoutEnv)
79+
if err != nil {
80+
log.Fatalln(err)
81+
}
7582
// start runtime init
76-
go InitHandler(sandbox, GetEnvOrDie("AWS_LAMBDA_FUNCTION_VERSION"), 30) // TODO: replace this with a custom init
83+
go InitHandler(sandbox, GetEnvOrDie("AWS_LAMBDA_FUNCTION_VERSION"), int64(invokeTimeoutSeconds)) // TODO: replace this with a custom init
7784

7885
// TODO: make the tracing server optional
7986
// start blocking with the tracing server
80-
err := http.ListenAndServe("0.0.0.0:"+lsOpts.InitTracingPort, http.DefaultServeMux)
87+
err = http.ListenAndServe("0.0.0.0:"+lsOpts.InitTracingPort, http.DefaultServeMux)
8188
if err != nil {
8289
log.Fatal("Failed to start debug server")
8390
}

0 commit comments

Comments
 (0)