-
Notifications
You must be signed in to change notification settings - Fork 935
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
chore: cache calls to signing key #15337
base: main
Are you sure you want to change the base?
Conversation
With this simple caching mechanism, each running instance should only have to make a single call at their first instantiation, and cache the result for the lifetime of the process. This call rarely fails, and adds ~200ms of each inbound hook, so caching across requests should cut down the time it takes to complete the processing. Instead of using a Redis cache and worrying about cache expiration strategies, if this ever fails a restart should evict the in-memory cache and trigger a new HTTP call for the key. Resolves pypi#4463 Signed-off-by: Mike Fiedler <miketheman@gmail.com>
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.
from a pure "ops" perspective i'm -1 on the assumed recovery scenario of restarting the process. while it is straightforward, how are we to recall that this could be the necessary action if it happened?
our gunicorn configuration simultaneously makes recovery a non-issue and reduces the impact of this cache: warehouse/gunicorn-prod.conf.py Lines 16 to 17 in 95c1b6e
i'm now -0 |
That is interesting, didn't know that. Does this mean we are recycling worker processes every few minutes now? We have 40 deployed instances of Does that align with your understanding of our current universe? If it does, should we consider the I couldn't find a Redis-backed cache pattern yet in the codebase, I guess we don't do that very much yet, unless I'm looking in the wrong place? |
Yes, this is effectively a diaper for memory leaks. Each worker gracefully reloads after 1920-2176 requests. This was put in place as our web processes slowly leaked memory over time leading to non graceful restarts. Ideally we just don't leak memory! I'd reconsider the value if we had demonstrably stable memory usage without. |
Note: We also tune worker count by the |
Makes sense! Did you have a way to test/verify memory leakage/profiling prior to production changes in mind, or is this a "let's double max_requests and observe" kind of thing?
WEB_CONCURRENCY was removed circa 2015 in https://github.com/pypi/warehouse/pull/741/files#diff-0a99231995da379e7aebabe76c9d849a23737a42c3b3a8994043e2aa80958424 and I can't find another tunable for gunicorn |
WEB_CONCURRENCY is native to gunicorn: https://docs.gunicorn.org/en/stable/settings.html#workers |
🤯 That'll learn me to read the docs more |
Measured via datadog, couldn't track it down. gave up! |
With this simple caching mechanism, each running instance should only have to make a single call at their first instantiation, and cache the result for the lifetime of the process.
This call rarely fails, and adds ~200ms of each inbound hook, so caching across requests should cut down the time it takes to complete the processing.
Instead of using a Redis cache and worrying about cache expiration strategies, if this ever fails a restart should evict the in-memory cache and trigger a new HTTP call for the key.
Resolves #4463