You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the task running AioS3FileSystem._copy_object_with_multipart_upload() is cancelled, the multipart upload is neither completed nor aborted, so the incomplete upload stays in the destination bucket (and its parts accrue storage) until a lifecycle rule removes it. This happens, for example, with asyncio.wait_for() timing out, task.cancel(), or a cancelled asyncio.gather().
The cleanup in pyathena/filesystem/s3_async.py (_copy_object_with_multipart_upload()) is except Exception:. asyncio.CancelledError is a BaseException, so it skips the wait for the running parts and the abort.
The part copies run with asyncio.to_thread(). Cancelling the awaiting tasks does not stop the threads, so parts that are already running finish after the cancellation and are stored in the upload.
#973 (PR #1036) added the abort for ordinary errors in the async multipart copy (a failed part or completion), and deliberately left cancellation out of scope.
Reproduction
Offline, on PR #1036 (0e75523), with the multipart requests mocked:
cancelled
abort called: False parts finished: []
parts finished after 0.5s: [1, 2]
The two running part copies complete after the cancellation has returned, and no AbortMultipartUpload is sent.
Expected
A cancelled async multipart copy waits for the part copies that are already running and then aborts the upload, as the sync path does for interrupts, and then re-raises the cancellation.
Problem
When the task running
AioS3FileSystem._copy_object_with_multipart_upload()is cancelled, the multipart upload is neither completed nor aborted, so the incomplete upload stays in the destination bucket (and its parts accrue storage) until a lifecycle rule removes it. This happens, for example, withasyncio.wait_for()timing out,task.cancel(), or a cancelledasyncio.gather().pyathena/filesystem/s3_async.py(_copy_object_with_multipart_upload()) isexcept Exception:.asyncio.CancelledErroris aBaseException, so it skips the wait for the running parts and the abort.asyncio.to_thread(). Cancelling the awaiting tasks does not stop the threads, so parts that are already running finish after the cancellation and are stored in the upload.S3FileSystem._finish_multipart_upload()catchesBaseException, waits for the parts that could not be cancelled, and aborts the upload.#973 (PR #1036) added the abort for ordinary errors in the async multipart copy (a failed part or completion), and deliberately left cancellation out of scope.
Reproduction
Offline, on PR #1036 (0e75523), with the multipart requests mocked:
Output:
The two running part copies complete after the cancellation has returned, and no AbortMultipartUpload is sent.
Expected
A cancelled async multipart copy waits for the part copies that are already running and then aborts the upload, as the sync path does for interrupts, and then re-raises the cancellation.
Environment