Repository navigation
fix(storage): honor timeout in upload_chunks_concurrently - #18765
abhishekacharya200 wants to merge 1 commit into
Conversation
upload_chunks_concurrently accepted a timeout but never passed it to the XML multipart requests, so initiate, every part upload, finalize and cancel always ran with the (61, 60) default. Pass it through to all of them, including the _upload_part worker. Callers who don't pass a timeout now get the documented 60 seconds (_DEFAULT_TIMEOUT, as every Blob upload and download already sends) instead of (61, 60), so only the connect timeout moves by one second. Fixes googleapis#18764
There was a problem hiding this comment.
Code Review
This pull request propagates the timeout parameter to various container and part operations within upload_chunks_concurrently (such as initiate, finalize, cancel, and _upload_part) and adds corresponding unit tests. The review feedback recommends wrapping the container.cancel call inside the exception handler in a nested try...except block to prevent cancellation failures from masking the original exception.
| except Exception: | ||
| container.cancel(blob._get_transport(client)) | ||
| container.cancel(blob._get_transport(client), timeout=timeout) | ||
| raise |
There was a problem hiding this comment.
If container.cancel raises an exception (for example, due to a timeout or network issue during the cleanup attempt), it will mask the original exception that triggered the except block. To ensure the original error is preserved and propagated to the caller for proper debugging, wrap the container.cancel call in a nested try...except block. Avoid silently ignoring the exception with a broad except Exception: pass block; instead, log the exception using logger.warning to aid in debugging and prevent masking underlying issues.
except Exception:
try:
container.cancel(blob._get_transport(client), timeout=timeout)
except Exception as e:
logger.warning("Failed to cancel container: %s", e)
raiseReferences
- Avoid broad
except Exception:blocks that silently returnNone. Instead, log the exception (e.g., usinglogger.warning) to aid in debugging and prevent masking underlying issues.
Fixes #18764
upload_chunks_concurrentlytakes atimeoutargument and documents it as the time to wait for the server response, but it never passed it on. The XML multipart requests it makes (initiate, each part upload, finalize, and cancel when something fails) all ran with the(61, 60)default of the media layer, so a caller could not make a stuck upload fail sooner or give a slow connection more time.This passes
timeouttoXMLMPUContainer.initiate,finalizeandcancel, and adds it to the_upload_partworker so everyXMLMPUPart.uploadgets it as well. Thread and process workers behave the same, since the timeout is a plain number or tuple.One small change for callers who don't pass a timeout: these requests now use the documented default of 60 seconds (
_DEFAULT_TIMEOUT, the value everyBlobupload and download already sends) instead of(61, 60). Only the connect timeout moves, by one second.The cleanup
cancelgets the same timeout as the other requests, so with a very short timeout the cancel itself can time out too. I kept it consistent with the rest, but I'm happy to leavecancelon the default if you'd rather keep the cleanup more forgiving.With the script from the issue, which records the timeout each request gets:
Added
test_upload_chunks_concurrently_passes_timeoutandtest_upload_chunks_concurrently_passes_timeout_to_cancel, which fail onmainand pass with this change. The existing tests that checked these calls now also check that the default timeout is sent, andtest__upload_partchecks that the worker hands its timeout to the part upload. The fulltests/unitsuite passes locally (2068 passed), and the noxfile'sruff==0.14.14import and format checks andflake8report nothing.