GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||
GeezerVison is showing github.com — perf(telemetry): don't let slow or rate-limited telemetry delay interpreter exit by vuanhphung · Pull Request #1028 · databricks/databricks-sql-python Conversation
|
| Case | main | this PR |
|---|---|---|
Live pecotesting, /telemetry-ext 200 (median; 12 vs 9 runs) |
188 ms | 184 ms |
Live pecotesting, runs where /telemetry-ext returned 429 (3 vs 6 runs) |
10.2 s, 10.2 s, 51.0 s | 3.07 s (max) |
Mock, 429 Retry-After: 1 (median, n=5) |
50.3 s | 3.07 s |
Mock, 503 without Retry-After (median, n=5) |
50.3 s | 3.07 s |
| Mock, telemetry responds in 8 s (median, n=5) | 8.07 s | 3.07 s |
| Mock, telemetry 200 in 40 ms (median, n=7) | 106 ms | 107 ms |
Over 15 interleaved live rounds, exit lag p95 went from 10.2 s to 3.07 s and max from 51.0 s to 3.07 s. The trade-off is in the 429 runs: main eventually delivered that batch (after 10–51 s), and this PR drops it at the 3 s bound. Every run that got a 200 delivered its telemetry on both. conn.close() itself is unchanged (~43 ms on a 40 ms-RTT mock, ~80 ms live). With 200 connections closing concurrently, close p50/p99 is 121/250 ms on main vs 126/247 ms here (noise), and the mock server received all 400 telemetry events on both.
New unit tests cover the executor (bounded daemon workers, result/exception propagation, shutdown draining queued work, wait_until_idle), the bounded exit wait across a shut-down executor, a subprocess test in which a quick send is delivered at exit and a stuck one doesn't block it (on main that subprocess hangs until it is killed), and a fork test showing that a child doesn't inherit the parent's in-flight sends. The full unit suite passes. test_telemetry_e2e.py, test_concurrent_telemetry.py and the close/cancel tests in test_driver.py pass against a live warehouse. Mock numbers come from a local Thrift-over-HTTP server with 40 ms RTT; live numbers come from interleaved single-connection runs against pecotesting.
N/A
This pull request and its description were written by Isaac.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
The final telemetry flush on close is submitted to a ThreadPoolExecutor, whose workers are joined at interpreter exit. When /telemetry-ext is slow or returns 429 (retried with 10 s sleeps), the process could not exit until the retries finished: 10-50 s on a rate-limited endpoint, up to the 900 s request timeout on a hung one. Run telemetry sends on daemon worker threads instead, and at exit wait at most EXIT_FLUSH_TIMEOUT_SECONDS (3 s) for in-flight sends, so the normal final flush is still delivered before the process exits. Signed-off-by: Vu Anh Phung <[email protected]> Co-authored-by: Isaac <[email protected]>
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Verdict: 1 Low
Looks good, with one low-severity edge case. A forked child can be left with a stale in-flight count, so its interpreter exit always waits the full 3 s. The daemon-executor design, the bounded atexit wait across executors that were already shut down, and the subprocess regression test all look correct for the main use case.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Sends in flight in the parent at fork time stayed counted in the child, so a child that sent its own telemetry always waited the full exit bound. Reset each executor's queue, workers, count and lock after fork (the parent still sends the work it queued), and start a worker before queueing so the count only covers work some worker will run. Signed-off-by: Vu Anh Phung <[email protected]> Co-authored-by: Isaac <[email protected]>
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
✅ No issues identified by the review bot.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
26efb872
Deployed
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.