Skip to content

Commit

Permalink
feat: requests timeout respecting CLOUD_RUN_TIMEOUT_SECONDS
Browse files Browse the repository at this point in the history
  • Loading branch information
garethgeorge committed Jun 12, 2024
1 parent ac7db72 commit 5f01e89
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
4 changes: 4 additions & 0 deletions funcframework/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ func convertBackgroundToCloudEvent(ceHandler http.Handler) http.Handler {
return
}
}
r, cancel := setTimeoutContextIfRequested(r)
if cancel != nil {
defer cancel()
}
ceHandler.ServeHTTP(w, r)
})
}
Expand Down
26 changes: 25 additions & 1 deletion funcframework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (
"os"
"reflect"
"runtime/debug"
"strconv"
"strings"
"time"

"github.com/GoogleCloudPlatform/functions-framework-go/internal/registry"
cloudevents "github.com/cloudevents/sdk-go/v2"
Expand Down Expand Up @@ -196,6 +198,10 @@ func wrapHTTPFunction(fn func(http.ResponseWriter, *http.Request)) (http.Handler
defer fmt.Println()
defer fmt.Fprintln(os.Stderr)
}
r, cancel := setTimeoutContextIfRequested(r)
if cancel != nil {
defer cancel()
}
defer recoverPanic(w, "user function execution", false)
fn(w, r)
}), nil
Expand All @@ -212,7 +218,10 @@ func wrapEventFunction(fn interface{}) (http.Handler, error) {
defer fmt.Println()
defer fmt.Fprintln(os.Stderr)
}

r, cancel := setTimeoutContextIfRequested(r)
if cancel != nil {
defer cancel()
}
if shouldConvertCloudEventToBackgroundRequest(r) {
if err := convertCloudEventToBackgroundRequest(r); err != nil {
writeHTTPErrorResponse(w, http.StatusBadRequest, crashStatus, fmt.Sprintf("error converting CloudEvent to Background Event: %v", err))
Expand Down Expand Up @@ -388,3 +397,18 @@ func writeHTTPErrorResponse(w http.ResponseWriter, statusCode int, status, msg s
w.WriteHeader(statusCode)
fmt.Fprint(w, msg)
}

// addTImeoutToRequestContext replaces the request's context with a cancellation if requested
func setTimeoutContextIfRequested(r *http.Request) (*http.Request, func()) {
timeoutStr := os.Getenv("CLOUD_RUN_TIMEOUT_SECONDS")
if timeoutStr == "" {
return r, nil
}
timeoutSecs, err := strconv.Atoi(timeoutStr)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not parse CLOUD_RUN_TIMEOUT_SECONDS as an integer value in seconds: %v", err)
return r, nil
}
ctx, cancel := context.WithTimeout(r.Context(), time.Duration(timeoutSecs)*time.Second)
return r.WithContext(ctx), cancel
}

0 comments on commit 5f01e89

Please # to comment.