Repository navigation
Conversation
`AsyncAppendableObjectWriter` and `_AsyncWriteObjectStream` overloaded a single `generation` argument: `None`/`0` created a new object via `WriteObjectSpec(if_generation_match=generation)`, while `N > 0` reopened an existing object via `AppendObjectSpec(generation=N)`. There was no way to request `WriteObjectSpec(appendable=True, if_generation_match=N)`, i.e. overwrite an object only if its current generation is still `N`, although the gRPC API and the other GCS client libraries support it. This adds an explicit `if_generation_match` parameter. It is set on `WriteObjectSpec` when creating a new object (`generation` is `None` or `0`; `generation=0` keeps meaning `if_generation_match=0` when the new parameter is not given) and is ignored when `generation > 0` selects an existing object to append to, so the redirect-retry path that reopens with the redirected generation is unaffected. Test Plan: ``` cd packages/google-cloud-storage PYTHONPATH=$PWD python -m pytest tests/unit/asyncio/test_async_write_object_stream.py tests/unit/asyncio/test_async_appendable_object_writer.py # 73 passed ruff check --select I --target-version=py310 --line-length=88 <changed files> ruff format --check --target-version=py310 --line-length=88 <changed files> flake8 <changed files> ``` Authored with an AI assistant.
There was a problem hiding this comment.
Code Review
This pull request adds support for the if_generation_match precondition parameter to the asynchronous appendable object writer and write object stream classes. It updates AsyncAppendableObjectWriter and _AsyncWriteObjectStream to accept, document, and propagate this parameter to the underlying BidiWriteObjectRequest. Unit tests have also been added to verify the correct handling of this parameter. There are no review comments to address, and I have no feedback to provide.
|
@yuxin00j Please add system tests for these changes in https://github.com/googleapis/google-cloud-python/blob/main/packages/google-cloud-storage/tests/system/test_rapid.py |
|
@yuxin00j , please see my comment http://shortn/_bOdi6IPxm9 |
…ss on AsyncAppendableObjectWriter
|
/gcbrun |
Summary
AsyncAppendableObjectWriteroverloadsgeneration:None/0creates a new object viaWriteObjectSpec(if_generation_match=generation), whileN > 0reopens an existing object viaAppendObjectSpec(generation=N). There was no way to passif_generation_match=N(N > 0) onWriteObjectSpec(overwrite only if the current generation matchesN) or other write preconditions (if_generation_not_match,if_metageneration_match,if_metageneration_not_match).This adds a
Preconditionsdataclass (if_generation_match,if_generation_not_match,if_metageneration_match,if_metageneration_not_match) accepted viapreconditions: Optional[Preconditions] = NoneonAsyncAppendableObjectWriter.__init__,AsyncAppendableObjectWriter.from_blob, and_AsyncWriteObjectStream.__init__:generationisNoneor0), all 4 precondition fields are populated onWriteObjectSpec(preconditions.if_generation_matchtakes precedence overgeneration=0, whilegeneration=0withoutpreconditionscontinues to setif_generation_match=0).generation > 0, including redirect takeover and reconnects after creation),if_metageneration_matchandif_metageneration_not_matchare forwarded onAppendObjectSpecand generation preconditions are ignored.Motivation: fsspec/gcsfs#1101 (compare-and-swap writes in gcsfs).
Test plan