-
Notifications
You must be signed in to change notification settings - Fork 468
feat: add uWSGI + gevent support with threading #15207
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
|
|
We add support for the combination of uWSGI + gevent when threads are also gevent-monkey-patched.
84e5d19 to
5efd1a3
Compare
Bootstrap import analysisComparison of import times between this PR and base. SummaryThe average import time from this PR is: 239 ± 3 ms. The average import time from base is: 243 ± 5 ms. The import time difference between this PR and base is: -4.0 ± 0.2 ms. Import time breakdownThe following import paths have shrunk:
|
Performance SLOsComparing candidate feat/uwsgi-gevent-thread-support (5efd1a3) with baseline main (1c3361c) 🟡 Near SLO Breach (6 suites)🟡 djangosimple - 30/30✅ appsecTime: ✅ 20.481ms (SLO: <22.300ms -8.2%) vs baseline: ~same Memory: ✅ 66.014MB (SLO: <67.000MB 🟡 -1.5%) vs baseline: +5.0% ✅ exception-replay-enabledTime: ✅ 1.338ms (SLO: <1.450ms -7.7%) vs baseline: +0.2% Memory: ✅ 64.149MB (SLO: <67.000MB -4.3%) vs baseline: +4.9% ✅ iastTime: ✅ 20.503ms (SLO: <22.250ms -7.9%) vs baseline: ~same Memory: ✅ 66.096MB (SLO: <67.000MB 🟡 -1.3%) vs baseline: +5.0% ✅ profilerTime: ✅ 15.593ms (SLO: <16.550ms -5.8%) vs baseline: ~same Memory: ✅ 54.004MB (SLO: <54.500MB 🟡 -0.9%) vs baseline: +4.9% ✅ resource-renamingTime: ✅ 20.518ms (SLO: <21.750ms -5.7%) vs baseline: ~same Memory: ✅ 66.208MB (SLO: <67.000MB 🟡 -1.2%) vs baseline: +5.0% ✅ span-code-originTime: ✅ 25.471ms (SLO: <28.200ms -9.7%) vs baseline: +0.3% Memory: ✅ 67.341MB (SLO: <69.500MB -3.1%) vs baseline: +5.2% ✅ tracerTime: ✅ 20.374ms (SLO: <21.750ms -6.3%) vs baseline: -0.4% Memory: ✅ 66.040MB (SLO: <67.000MB 🟡 -1.4%) vs baseline: +5.0% ✅ tracer-and-profilerTime: ✅ 22.694ms (SLO: <23.500ms -3.4%) vs baseline: +0.2% Memory: ✅ 67.855MB (SLO: <68.000MB 🟡 -0.2%) vs baseline: +4.9% ✅ tracer-dont-create-db-spansTime: ✅ 19.340ms (SLO: <21.500ms 📉 -10.0%) vs baseline: ~same Memory: ✅ 66.021MB (SLO: <67.000MB 🟡 -1.5%) vs baseline: +4.7% ✅ tracer-minimalTime: ✅ 16.615ms (SLO: <17.500ms -5.1%) vs baseline: -0.4% Memory: ✅ 65.998MB (SLO: <67.000MB 🟡 -1.5%) vs baseline: +4.7% ✅ tracer-nativeTime: ✅ 20.518ms (SLO: <21.750ms -5.7%) vs baseline: +0.5% Memory: ✅ 67.997MB (SLO: <72.500MB -6.2%) vs baseline: +4.9% ✅ tracer-no-cachesTime: ✅ 18.470ms (SLO: <19.650ms -6.0%) vs baseline: ~same Memory: ✅ 65.985MB (SLO: <67.000MB 🟡 -1.5%) vs baseline: +4.9% ✅ tracer-no-databasesTime: ✅ 18.747ms (SLO: <20.100ms -6.7%) vs baseline: -0.2% Memory: ✅ 65.990MB (SLO: <67.000MB 🟡 -1.5%) vs baseline: +5.0% ✅ tracer-no-middlewareTime: ✅ 20.171ms (SLO: <21.500ms -6.2%) vs baseline: ~same Memory: ✅ 65.956MB (SLO: <67.000MB 🟡 -1.6%) vs baseline: +4.7% ✅ tracer-no-templatesTime: ✅ 20.219ms (SLO: <22.000ms -8.1%) vs baseline: -0.5% Memory: ✅ 66.019MB (SLO: <67.000MB 🟡 -1.5%) vs baseline: +4.8% 🟡 errortrackingdjangosimple - 6/6✅ errortracking-enabled-allTime: ✅ 18.081ms (SLO: <19.850ms -8.9%) vs baseline: +0.2% Memory: ✅ 66.159MB (SLO: <66.500MB 🟡 -0.5%) vs baseline: +5.1% ✅ errortracking-enabled-userTime: ✅ 18.005ms (SLO: <19.400ms -7.2%) vs baseline: -0.3% Memory: ✅ 66.218MB (SLO: <66.500MB 🟡 -0.4%) vs baseline: +5.3% ✅ tracer-enabledTime: ✅ 18.083ms (SLO: <19.450ms -7.0%) vs baseline: ~same Memory: ✅ 65.805MB (SLO: <66.500MB 🟡 -1.0%) vs baseline: +4.7% 🟡 errortrackingflasksqli - 6/6✅ errortracking-enabled-allTime: ✅ 2.068ms (SLO: <2.300ms 📉 -10.1%) vs baseline: -0.2% Memory: ✅ 52.455MB (SLO: <53.500MB 🟡 -2.0%) vs baseline: +4.6% ✅ errortracking-enabled-userTime: ✅ 2.070ms (SLO: <2.250ms -8.0%) vs baseline: ~same Memory: ✅ 52.573MB (SLO: <53.500MB 🟡 -1.7%) vs baseline: +4.9% ✅ tracer-enabledTime: ✅ 2.071ms (SLO: <2.300ms -10.0%) vs baseline: +0.1% Memory: ✅ 52.612MB (SLO: <53.500MB 🟡 -1.7%) vs baseline: +4.9% 🟡 flasksimple - 18/18✅ appsec-getTime: ✅ 4.582ms (SLO: <4.750ms -3.5%) vs baseline: -0.2% Memory: ✅ 62.364MB (SLO: <65.000MB -4.1%) vs baseline: +4.9% ✅ appsec-postTime: ✅ 6.632ms (SLO: <6.750ms 🟡 -1.7%) vs baseline: +0.1% Memory: ✅ 62.408MB (SLO: <65.000MB -4.0%) vs baseline: +5.0% ✅ appsec-telemetryTime: ✅ 4.587ms (SLO: <4.750ms -3.4%) vs baseline: +0.1% Memory: ✅ 62.365MB (SLO: <65.000MB -4.1%) vs baseline: +4.8% ✅ debuggerTime: ✅ 1.854ms (SLO: <2.000ms -7.3%) vs baseline: +0.1% Memory: ✅ 45.179MB (SLO: <47.000MB -3.9%) vs baseline: +4.7% ✅ iast-getTime: ✅ 1.860ms (SLO: <2.000ms -7.0%) vs baseline: +0.2% Memory: ✅ 42.110MB (SLO: <49.000MB 📉 -14.1%) vs baseline: +4.9% ✅ profilerTime: ✅ 1.912ms (SLO: <2.100ms -9.0%) vs baseline: -0.2% Memory: ✅ 46.601MB (SLO: <47.000MB 🟡 -0.8%) vs baseline: +4.7% ✅ resource-renamingTime: ✅ 3.357ms (SLO: <3.650ms -8.0%) vs baseline: -0.4% Memory: ✅ 52.562MB (SLO: <53.500MB 🟡 -1.8%) vs baseline: +4.8% ✅ tracerTime: ✅ 3.356ms (SLO: <3.650ms -8.1%) vs baseline: ~same Memory: ✅ 52.534MB (SLO: <53.500MB 🟡 -1.8%) vs baseline: +4.8% ✅ tracer-nativeTime: ✅ 3.351ms (SLO: <3.650ms -8.2%) vs baseline: ~same Memory: ✅ 54.322MB (SLO: <60.000MB -9.5%) vs baseline: +4.8% 🟡 recursivecomputation - 8/8✅ deepTime: ✅ 309.662ms (SLO: <320.950ms -3.5%) vs baseline: +0.3% Memory: ✅ 32.676MB (SLO: <34.500MB -5.3%) vs baseline: +4.9% ✅ deep-profiledTime: ✅ 328.282ms (SLO: <359.150ms -8.6%) vs baseline: +0.2% Memory: ✅ 38.523MB (SLO: <39.000MB 🟡 -1.2%) vs baseline: +4.7% ✅ mediumTime: ✅ 7.024ms (SLO: <7.400ms -5.1%) vs baseline: +0.2% Memory: ✅ 31.850MB (SLO: <34.000MB -6.3%) vs baseline: +4.8% ✅ shallowTime: ✅ 0.942ms (SLO: <1.050ms 📉 -10.3%) vs baseline: ~same Memory: ✅ 31.890MB (SLO: <34.000MB -6.2%) vs baseline: +4.9% 🟡 telemetryaddmetric - 30/30✅ 1-count-metric-1-timesTime: ✅ 2.995µs (SLO: <20.000µs 📉 -85.0%) vs baseline: +1.1% Memory: ✅ 31.909MB (SLO: <34.000MB -6.1%) vs baseline: +4.8% ✅ 1-count-metrics-100-timesTime: ✅ 204.258µs (SLO: <220.000µs -7.2%) vs baseline: -0.6% Memory: ✅ 31.850MB (SLO: <34.000MB -6.3%) vs baseline: +4.6% ✅ 1-distribution-metric-1-timesTime: ✅ 3.281µs (SLO: <20.000µs 📉 -83.6%) vs baseline: -1.2% Memory: ✅ 31.929MB (SLO: <34.000MB -6.1%) vs baseline: +4.9% ✅ 1-distribution-metrics-100-timesTime: ✅ 216.168µs (SLO: <220.000µs 🟡 -1.7%) vs baseline: -0.4% Memory: ✅ 31.909MB (SLO: <34.000MB -6.1%) vs baseline: +5.0% ✅ 1-gauge-metric-1-timesTime: ✅ 2.204µs (SLO: <20.000µs 📉 -89.0%) vs baseline: -0.2% Memory: ✅ 31.870MB (SLO: <34.000MB -6.3%) vs baseline: +4.7% ✅ 1-gauge-metrics-100-timesTime: ✅ 137.094µs (SLO: <150.000µs -8.6%) vs baseline: ~same Memory: ✅ 31.890MB (SLO: <34.000MB -6.2%) vs baseline: +4.9% ✅ 1-rate-metric-1-timesTime: ✅ 3.174µs (SLO: <20.000µs 📉 -84.1%) vs baseline: +2.5% Memory: ✅ 31.909MB (SLO: <34.000MB -6.1%) vs baseline: +5.0% ✅ 1-rate-metrics-100-timesTime: ✅ 214.696µs (SLO: <250.000µs 📉 -14.1%) vs baseline: -0.7% Memory: ✅ 31.890MB (SLO: <34.000MB -6.2%) vs baseline: +4.9% ✅ 100-count-metrics-100-timesTime: ✅ 20.637ms (SLO: <22.000ms -6.2%) vs baseline: +1.2% Memory: ✅ 31.909MB (SLO: <34.000MB -6.1%) vs baseline: +5.0% ✅ 100-distribution-metrics-100-timesTime: ✅ 2.252ms (SLO: <2.300ms -2.1%) vs baseline: +0.5% Memory: ✅ 31.949MB (SLO: <34.000MB -6.0%) vs baseline: +5.0% ✅ 100-gauge-metrics-100-timesTime: ✅ 1.416ms (SLO: <1.550ms -8.7%) vs baseline: +0.9% Memory: ✅ 31.850MB (SLO: <34.000MB -6.3%) vs baseline: +4.7% ✅ 100-rate-metrics-100-timesTime: ✅ 2.220ms (SLO: <2.550ms 📉 -12.9%) vs baseline: +1.0% Memory: ✅ 31.850MB (SLO: <34.000MB -6.3%) vs baseline: +4.8% ✅ flush-1-metricTime: ✅ 4.518µs (SLO: <20.000µs 📉 -77.4%) vs baseline: +0.2% Memory: ✅ 31.909MB (SLO: <34.000MB -6.1%) vs baseline: +4.9% ✅ flush-100-metricsTime: ✅ 175.586µs (SLO: <250.000µs 📉 -29.8%) vs baseline: -0.1% Memory: ✅ 31.890MB (SLO: <34.000MB -6.2%) vs baseline: +5.0% ✅ flush-1000-metricsTime: ✅ 2.143ms (SLO: <2.500ms 📉 -14.3%) vs baseline: -0.2% Memory: ✅ 32.676MB (SLO: <34.500MB -5.3%) vs baseline: +4.7%
|
| try: | ||
| proc.wait(timeout=3) | ||
| except subprocess.TimeoutExpired: | ||
| # If we time out, it means uwsgi started successfully and is |
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.
worth sending a single request to make sure the app is actually up?
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.
what if it deadlocks?
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.
Based on the uwsgi config we're using, if the app is not available the process terminates straight away. I don't think it's possible to deadlock here because we are waiting 3 seconds and if the process has not terminated by then we forcibly kill it.
|
|
||
| @ModuleWatchdog.after_module_imported("gevent.monkey") | ||
| def _(_): | ||
| # uWSGI + gevent support: when the application module is imported, the |
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.
is this caused by us or a generic uWSGI + gevent bug?
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 is caused by us unloading _thread. I'm not quite sure yet why this causes the module lock to compute a different owner between the acquire and release 🤔 So this is more of a workaround than an actual fix
Description
We add support for the combination of uWSGI + gevent when threads are also gevent-monkey-patched.