-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: allow proxying readiness checks to the function #145
feat: allow proxying readiness checks to the function #145
Conversation
83d5ecf
to
318d12d
Compare
Allow setting an endpoint path for the function readiness check via an ENV variable `function_ready_endpoint` When this value is set, the requests to `/_/ready` will execute an empty GET request with/to the configured endpoint. This allows the function authors to implement custom readiness check logic. This custom request is checked _after_ the the standard liviness checks and the ConcurrencyLimiter check. For a completely custom readiness check, the function should be deployed with `max_inflight == 0` and `function_ready_endpoint` to the custom path. Signed-off-by: Lucas Roesler <roesler.lucas@gmail.com>
318d12d
to
fd43548
Compare
I have tested this, and the functionality appears to work as expected. I built a golang fn that had a readiness endpoint of |
One note: the readiness endpoint seems to emit logs, which should probably be silent by default. |
This is a priority to get merged for me, because if the gateway forwards traffic to a fn before it is initially ready, while the handler itself is not yet available in the fn to process the invocation, this would likely result in errors. This error case is similar to the Istio issue we previously solved for, where the gateway was sending traffic to the pod just a few milliseconds early. |
@kevin-lindsay-1 do you mean the error log or the proxy log line? I would have to add a bit more code to make that log line disappear because I am reusing the function proxy implementation, it just looks like any other request at the moment? The error log line should never happen, if you are seeing that, then i am very curious for more details. |
On more thing, we already exclude the kube-probe from the logs
so ... it should be omitted if/when i pass the headers along |
I'm pretty sure I was seeing the proxy log line. Looked like the one you in the code example above. I'd be fine with a follow-up patch, if I can confirm the behavior. It didn't seem to do it after the initial start, so it might have been an "error" due to not passing initial readiness. |
When proxying the readiness request to the upstream function, we should copy the original request headers. This allows the handler to use headers, if needed. It also allows the of-watchdog to suppress the noisy request logging for readiness checks. Signed-off-by: Lucas Roesler <roesler.lucas@gmail.com>
Pretty easy to pass the headers along, i just pushed a followup commit to copy them from the original request, this should now include the User-Agent and allow the proxy log to be suppressed (if the user agent contains "kube-probe") |
// otherwise it will just route to `/`, typically this shouldn't be used or set | ||
readyReq.RequestURI = r.endpoint | ||
readyReq.Header = req.Header.Clone() | ||
r.functionHandler.ServeHTTP(w, readyReq) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why wouldn't we http.DefaultClient.Do
this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That requires re-parsing all of the config options to build the correct URL etc. The existing function handler already exists and has all of the desired configuration and URL parsing/construction.
I think it also matches the semantics of the feature:
"during readiness, invoke the function in a certain way"
This code matches this semantic directly because we pass down the function invoker (i.e. handler) and then invoke it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexellis the doc strings have been added and it also ensures the basic unwrapped handler is used in the readiness check.
User read_path instead of function_ready_endpoint. This should be clearer that it needs to be a path on the function and match prior art in other projects. Signed-off-by: Lucas Roesler <roesler.lucas@gmail.com>
Document why we use the base function handler to provide custom ready checks to all function modes. Additionally, make sure that the unwrapped function handler is passed to the readiness check. This ensures that readiness checks do not count toward the concurrency limit Signed-off-by: Lucas Roesler <roesler.lucas@gmail.com>
@@ -65,7 +65,16 @@ func main() { | |||
os.Exit(1) | |||
} | |||
|
|||
requestHandler := buildRequestHandler(watchdogConfig, watchdogConfig.PrefixLogs) | |||
if watchdogConfig.ReadyEndpoint != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can omit this because it will generate a lot of logs over the course of a year
Hi @LucasRoesler I did some more testing on this and wanted to share the results:
|
Document why we use the base function handler to provide custom ready checks to all function modes. Additionally, make sure that the unwrapped function handler is passed to the readiness check. This ensures that readiness checks do not count toward the concurrency limit Review by AE - reverts change to faas-middleware, by introducing an interface. Closes: #145 Signed-off-by: Lucas Roesler <roesler.lucas@gmail.com> Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
I have a fix for this, it wasn't a new issue in a new PR along with your commits (for you to get credit), but was possibly triggered by the changes. Since you may want this PR to count towards hacktoberfest, feel free to open a PR to the README file to update how this feature works and I'll merge that after. |
Document why we use the base function handler to provide custom ready checks to all function modes. Additionally, make sure that the unwrapped function handler is passed to the readiness check. This ensures that readiness checks do not count toward the concurrency limit Review by AE - reverts change to faas-middleware, by introducing an interface. Closes: #145 Signed-off-by: Lucas Roesler <roesler.lucas@gmail.com> Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
Allow setting an endpoint path for the function readiness check via an ENV variable
function_ready_endpoint
When this value is set, the requests to
/_/ready
will execute an empty GET request with/to the configured endpoint. This allows the function authors to implement custom readiness check logic.This custom request is checked after the the standard liveliness checks and the ConcurrencyLimiter check. For a completely custom readiness check, the function should be deployed with
max_inflight == 0
andfunction_ready_endpoint
to the custom path.Motivation and Context
Resolved #144
How Has This Been Tested?
Additional unit tests have been added
Manually tested with a custom python function
Types of changes
Checklist:
git commit -s