-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[proxy] Pre-flight requests to server /api/* endpoints #14897
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
Conversation
started the job as gitpod-build-af-proxy-api-to-slow-server.22 because the annotations in the pull request description changed |
components/proxy/conf/Caddyfile
Outdated
import upstream_headers | ||
import upstream_connection | ||
|
||
# required for smooth streaming of terminal logs | ||
flush_interval -1 |
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'd like to be able to replace the body of these reverse_proxy
directives with a snippet to reduce duplication but ran into this Caddy bug with nested imports: caddyserver/caddy#4914
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.
Really sad that we have to duplicate 3 times...
💡
Would it work do do something like:
handle_response @slow { ... }
# fall-through fast/default case
uri strip_prefix /api
reverse_proxy server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_headers
import upstream_connection
# required for smooth streaming of terminal logs
flush_interval -1
}
That way we only need to duplicate once...?
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.
Looking at this: if we used forward_auth
it seems we can even do away with one more level of nesting.
handle @backend {
...
forward_auth server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
uri /api/feature-flags/slow-database
copy_headers {
X-Gitpod-Slow-Database
}
}
handle_response @slow ...
reverse_proxy ...
@andrew-farries WDYT?
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.
Will take a look at forward_auth
. When I looked before it didn't seem to match our use case, but will look again 👀
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.
Would it work do do something like:
...
This looks like it should work according the Caddy docs on intercepting responses:
I tried a simplified version in this Gist:
https://gist.github.com/andrew-farries/a2ac60d51e6c812ded573720c1ffabf6
but the fallthrough case doesn't work. Caddy docs say:
When a response handler is invoked, the response from the backend is not written to the client, and the configured handle_response route will be executed instead, and it is up to that route to write a response. If the route does not write a response, then request handling will continue with any handlers that are ordered after this reverse_proxy.
but despite the @fast
and @none
matchers not writing a response, the respond
directive after the reverse_proxy
directive never gets run.
(You can try it for yourself with caddy run --watch
and then http :2015/api/foo
)
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.
Another alternative to reduce duplication here would be to have the feature-flags/slow-database
endpoint always set the X-Gitpod-Slow-Database
response header. It currently only does so on 200 OK
responses:
gitpod/components/server/src/feature-flag/featureflag-controller.ts
Lines 24 to 44 in c154c32
protected addSlowDatabaseFeatureFlagHandler(router: express.Router) { | |
router.get("/slow-database", async (req, res) => { | |
if (!User.is(req.user)) { | |
res.sendStatus(401); | |
return; | |
} | |
try { | |
const flagValue = await getExperimentsClientForBackend().getValueAsync("slow_database", false, { | |
user: req.user, | |
}); | |
res.setHeader("X-Gitpod-Slow-Database", flagValue.toString()); | |
res.status(200); | |
res.end(); | |
} catch (error) { | |
log.error(`failed to retrieve value of 'slow_database' feature flag: ${error.message}`); | |
res.status(500); | |
res.end(); | |
} | |
}); | |
} |
That way we could remove the @headerNotPresent
response matcher.
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.
Changed to use forward_auth
, copy_headers
and request matchers as we discussed in sync today.
This needs #14930 to land first to ensure the api/feature-flags/slow-database
endpoint returns 200 OK
consistently.
/werft run 👍 started the job as gitpod-build-af-proxy-api-to-slow-server.25 |
Currently I get an "Unauthorized", and figured that this needs to be rebased on #14930 (as you mentioned above 😆 ) |
edb4963
to
9e4168a
Compare
I see a lot of these lines being logged, bc we forward websocket Upgrade-requests to the server, but on a rewritten URi. |
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.
And it works - sloooooowly 😆
Nice work, @andrew-farries ! 🚀
/hold bc I think we should adress #14897 (comment) before we merge
I'm not sure why we see these errors at all. In the gitpod/components/proxy/conf/Caddyfile Lines 207 to 230 in 54d7c00
and the other with a path matcher for gitpod/components/proxy/conf/Caddyfile Lines 232 to 270 in 54d7c00
AIUI The |
After a sync today we determined that the cause of the websocket errors in the server log was websocket requests arriving at #14974 should resolve this. |
54d7c00
to
9e4168a
Compare
Using the version of |
Before serving /api requests, make a 'pre-flight' request to `/api/feature-flags/slow-database` and use the `X-Gitpod-Slow-Database` header in the response to decide where to send the actual request; either to the regular `server` service or the new `slow-server` service.
9e4168a
to
00ec6a2
Compare
/unhold |
Description
Before handling
server
/api
requests, make a 'pre-flight' request to/api/feature-flags/slow-database
(onserver
) and use theX-Gitpod-Slow-Database
header in the response to decide where to send the actual request; either to the regularserver
service or the newslow-server
service.This allows us to use a feature flag to simulate the performance of these endpoints when they use a higher latency database connection.
Related Issue(s)
Part of #9198
Closes #14960.
How to test
slow_database
feature flag (non-production environment) to this (replacing the user id with your user id in the preview):Release Notes
Documentation
Werft options:
If enabled this will build
install/preview
Valid options are
all
,workspace
,webapp
,ide
,jetbrains
,vscode
,ssh