Skip to content

fix: avoid ZeroDivisionError when a CloudFetch download takes no measurable time - #977

Open
maharanay22 wants to merge 1 commit into
databricks:mainfrom
maharanay22:fix-cloudfetch-zero-duration
Open

maharanay22 wants to merge 1 commit into
databricks:mainfrom
maharanay22:fix-cloudfetch-zero-duration

Conversation

@maharanay22

Copy link
Copy Markdown

What type of PR is this?

  • Bug Fix

Description

ResultSetDownloadHandler.run() timed each CloudFetch download with time.time(), and _log_download_metrics() divided the byte count by that duration. On Windows with Python 3.12 and earlier, time.time() only advances about every 15.6 ms, so a chunk that downloads within one tick has a measured duration of exactly 0. The whole fetch then fails with ZeroDivisionError: float division by zero from a logging call. With an instant mock HTTP client, 196 of 200 downloads failed this way on Windows 11 / Python 3.12.

This PR measures the download with time.perf_counter(), which is monotonic and high resolution, and logs the speed as inf when the duration is not positive, so logging can never fail a download. The log format is otherwise unchanged, and no slow-download warning is emitted in that case. I used perf_counter rather than time.monotonic on purpose, because monotonic has the same ~15.6 ms resolution on Windows with Python 3.12 and earlier.

How is this tested?

  • Unit tests
  • Manually

New test_run_successful_when_clock_does_not_advance freezes the clock and runs run() without patching _log_download_metrics. It fails on main with ZeroDivisionError: float division by zero and passes with this change. Full unit suite: 1021 passed, 5 skipped. Manually, the 200-download loop above now succeeds 200 of 200 times on Windows 11 / Python 3.12.

Related Tickets & Documents

The speed logging was added in #654. The existing tests in tests/unit/test_downloader.py patch out _log_download_metrics "to avoid division by zero"; I left those in place to keep this PR small.

…urable time

ResultSetDownloadHandler.run() timed each download with time.time() and
_log_download_metrics() divided the byte count by that duration. On
Windows with Python 3.12 and earlier, time.time() only advances about
every 15.6 ms, so a chunk that downloads within one tick has a duration
of exactly 0 and the whole fetch fails with ZeroDivisionError from a
logging call.

Measure the download with time.perf_counter(), which is monotonic and
high resolution, and report the speed as inf when the duration is not
positive so logging can never fail a download.

Signed-off-by: Maha Rana Yadavalli <271375718+maharanay22@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant