Skip to content

An interrupted S3File write leaves the upload behind when CreateMultipartUpload is in flight #1077

Closed

Description

@laughingman7743

Problem

An S3File write that is interrupted while its CreateMultipartUpload request is running leaves the created upload behind, incomplete, as #1076 describes for the multipart copy.

S3File._initiate_upload() sends CreateMultipartUpload in the writer's thread (pyathena/filesystem/s3.py :3588 on master d989767). fsspec's flush() calls it when the buffer first reaches the block size. If a KeyboardInterrupt is raised during the request, self.multipart_upload is never set. S3 may still create the upload. discard() and _close_without_commit() abort only an upload whose ID they know (:3770), so nothing aborts it. This affects open(..., "wb"), appends, and the buffered paths of pipe_file() and put_file() for data larger than the block size.

AioS3FileSystem runs these writes in asyncio.to_thread. A cancellation there does not interrupt the thread, so the write runs to completion instead of leaving an upload behind.

Reproduction

This finding comes from reading the code and was not run. A KeyboardInterrupt raised in the writer's thread during the CreateMultipartUpload request propagates out of _initiate_upload() before the response is assigned, so the upload ID is unknown to every later cleanup. The copy case in #1076 was reproduced offline by delivering SIGINT during a mocked creation; the writer has the same structure.

Environment

PyAthena master d989767, Python 3.13.1, botocore 1.43.102, S3FileSystem.

Proposed fix (optional)

As in the fix for #1076: send the creation on the file's executor and wait for its future. On an interrupt while waiting, wait for the creation, keep the returned upload so that discard() aborts it, and re-raise. This belongs with the move of the S3File multipart writer, step 4 of #1053, and should be validated with an offline test that interrupts a held creation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions