-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat: add metrics=timings preference to prefer header #3507
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
base: main
Are you sure you want to change the base?
Conversation
953a808
to
0da1e8c
Compare
e5d6008
to
bfd02a2
Compare
Deprecating the config does not mean to remove it from the code (right now), only that it's not recommended anymore (could be removed in the future). It should be mentioned in comments and in the docs that it's deprecated in favor of the new feature. See, for example: 6c3d7a9 and https://postgrest.org/en/latest/references/api/preferences.html#single-json-object-as-function-parameter |
src/PostgREST/App.hs
Outdated
-- the preference metrics=timings cant be used before it is parsed, hence | ||
-- parseTime will be calculated for all requests | ||
(parseTime, apiReq@ApiRequest{..}) <- withTiming True $ liftEither . mapLeft Error.ApiRequestError $ ApiRequest.userApiRequest conf req body sCache |
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.
Ah, so it's not possible to disable ALL timings with Prefer: metrics=timings
, without parsing the headers first. So it's not a perfect replacement for server-timings-enabled = false
, since some timings will be calculated even if the header is not sent: the "jwt" and "parse" timings as far as I can see.
Not sure if it's OK to always calculate these timings, I believe it will still affect the performance as mentioned in the issue. cc: @steve-chavez
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.
Hm, so here we're forcing to always calculate the time for parsing? That would defeat the whole purpose of #3410
But I understand that we first need to parse to get the header. I guess we would need to do this in a step separate from userApiRequest
, but that's messy.
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.
So far the parse
and response
timings (ref) have not been that useful because they're always fast.
Another option could be to omit the parse
timing when doing Prefer: metrics=timings
or we could just remove support for the above mentioned. Then we wouldn't have this problem.
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 was thinking to do a breaking change and remove the parse
time now. But then I thought: wouldn't it be simpler to omit the parse
time when Prefer: metric=timings
is requested?
It would just be:
Server-Timing: jwt;dur=14.9, plan;dur=109.0, transaction;dur=353.2, response;dur=4.4
We could point that out in the docs.
@taimoorzaeem I believe that should unblock this feature.
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.
Yes, that would be much simpler. Let's implement it this way.
57a6f25
to
00cca6c
Compare
CHANGELOG.md
Outdated
@@ -57,6 +58,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). | |||
+ Return new `PGRST303` error when jwt claims decoding fails | |||
- #3906, Return `PGRST125` and `PGRST126` errors instead of empty json - @taimoorzaeem | |||
|
|||
### Deprecated | |||
|
|||
- #3410, The config `server-timing-enabled` is deprecated. Use `metrics=timings` prefer header instead - @taimoorzaeem |
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.
Now that server-timing-enabled
has different functionality than Prefer: metrics=timings
, I don't think we can deprecate it/remove it in the future. At least for now.
00cca6c
to
68f42f8
Compare
This allows obtaining the preferences header before doing the full parse on userApiRequest. Which is needed by PostgREST#3507.
docs/references/api/preferences.rst
Outdated
.. note:: | ||
|
||
When timings are requested with this header, we can't tell the ``parse`` stage timings. This is because we are past the "parse" stage when this preference itself is parsed. |
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.
This didn't look good. So I thought of a simpler way: #4057.
With this, we won't measure the parse time of the Preferences header, but that's fine as its parsing is simple and its input small.
The bulk of the parse
stage is really in QueryParams.parse
(URL query string parsing) which is still maintained.
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.
To be clear, once you rebase on top of #4057, the Prefer: metric=timings
resposne now should contain the same information as when the server-timing-enabled
config is set.
This allows obtaining the preferences header before doing the full parse on userApiRequest. Which is needed by #3507.
68f42f8
to
c6c1545
Compare
-- Now that we also calculate the timings when Prefer: metrics=timings, | ||
-- how do we get that preference here? |
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.
@steve-chavez We need the preference here too. I am not sure about this but I think we should think about storing the ApiRequest
result in AppState
. This way it would be easier to access already parsed request information at any stage in the code.
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 should just refactor to remove the Auth.middleware
approach. I've never liked that one as it hides side effects and obscures logic. It might allow us to remove the unsafePerformIO
from Auth.hs too:
postgrest/src/PostgREST/Auth.hs
Lines 190 to 198 in e4a2095
authResultKey :: Vault.Key (Either Error AuthResult) | |
authResultKey = unsafePerformIO Vault.newKey | |
{-# NOINLINE authResultKey #-} | |
getResult :: Wai.Request -> Maybe (Either Error AuthResult) | |
getResult = Vault.lookup authResultKey . Wai.vault | |
jwtDurKey :: Vault.Key Double | |
jwtDurKey = unsafePerformIO Vault.newKey |
Once that's done you should be able to use/get the prefer value value before validating the JWT.
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.
Agreed. Let me refactor this.
Closes #3410.