bmanan7 commented on PR #71064: URL: https://github.com/apache/airflow/pull/71064#issuecomment-5205611886
Thanks for picking this up. Nice to see it go straight to `append_block()` with `appendpos_condition` rather than `upload_blob(blob_type="AppendBlob")`, since that distinction is easy to miss, and the block-blob fallback for existing objects is exactly right. One thing I think is worth handling before this lands: the chunk loop can leave a lifecycle partially applied, and nothing records how much of it landed. Take a segment larger than the 4 MiB block limit, say 10 MiB split into A1, A2, A3: 1. `append_block(A1, offset=0)` commits. The blob is now 4 MiB. 2. `append_block(A2, offset=4MiB)` hits a transient error, so `write()` returns False. 3. `upload()` sees `has_uploaded=False` and correctly leaves the local file intact so the segment can be retried (the behaviour added in #70860). The blob now holds A1, while the local file still holds A1+A2+A3. On the next upload to the same key, `offset` is read as `properties.size`, which is 4 MiB, and the whole local file is appended from there. A1 ends up stored twice. `appendpos_condition` does not catch this: the blob really is 4 MiB at that point, so the guard passes. It protects against writing at the wrong offset, not against re-sending content that already landed. The block-blob path never had this problem because its single `overwrite=True` PUT is atomic, so a lifecycle could not end half-applied. It needs a second upload against the same key to surface, so in practice a deferrable resume or a reschedule poke whose individual lifecycle writes more than 4 MiB. Rare, but it is the same class of duplication that #70860 just fixed, which is why I thought it worth raising. The awkward part is that `write()` receives the log string and returns a bool, so it has no way to tell `upload()` "4 of 10 MiB committed" or to trim the local file itself. A few directions that might work: - Retry the remaining chunks in place before giving up, which narrows the window without closing it. - Return bytes written, or move the chunking up into `upload()`, so the committed prefix can be trimmed from the local file and the "local file is exactly what has not been uploaded" invariant holds again. - Simplest option: do not chunk, and fall back to the block-blob path for segments over the limit, keeping the append path atomic. --- Drafted-by: Claude Code (Opus 5); reviewed by @bmanan7 before posting -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
