Skip to content

chore(spanner): restore CrossSync parity for snapshot.py - #18380

Open
olavloite wants to merge 1 commit into
mainfrom
spanner-restore-cross-sync-parity
Open

olavloite wants to merge 1 commit into
mainfrom
spanner-restore-cross-sync-parity

Conversation

@olavloite

Copy link
Copy Markdown
Contributor

snapshot.py is generated from _async/snapshot.py, but the generated file had picked up code the async source never had. Running the generator deleted it. The drift came in via 25aba4f (PR #16488): a branch authored before the CrossSync migration but merged after it, so it edited snapshot.py as if that file were still hand-maintained.

Fixes:

  • Port the _transaction_begin_event guard and the read()/execute_sql() docstrings back into _async/snapshot.py, so the generator reproduces them instead of dropping them.
  • Use CrossSync.Lock / CrossSync.Event instead of raw threading, so the primitives survive the async -> sync conversion.
  • De-duplicate the guard: read() and execute_sql() had identical copies, now one _wait_for_transaction_begin() helper.
  • Async fix: read()/execute_sql() raised "Transaction has not begun." when a concurrent inline begin was in flight. They now wait for it, matching the sync client.
  • generate.py: format with ruff instead of black. The repo uses ruff, so every run produced a formatting-only diff.
  • generate.py: exit non-zero when given a file instead of a directory. It used to print "Generated 0 artifacts" and do nothing, which is how the drift went unnoticed.
  • Delete snapshot_helpers.py, an orphaned generated file with a stale copy of execute_sql that nothing imports.
  • Add tests for the guard, which had none.
  • Speed up 4 tests that each waited out the real 30s begin timeout. They passed, just slowly; two were already slow on main. They now patch the timeout constant and assert the specific error message. Unit suite: 204s -> 57s.

Regenerating now leaves the tree unchanged:
PYTHONPATH=.cross_sync python3 .cross_sync/generate.py \ google/cloud/spanner_v1/_async/ git diff --exit-code google/cloud/spanner_v1/

@olavloite
olavloite requested a review from a team as a code owner September 15, 2026 15:01

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a mechanism to coordinate concurrent requests beginning a transaction in the Spanner client by adding a _wait_for_transaction_begin method and an event-based synchronization mechanism to prevent race conditions. It also updates the cross-sync generation script to use ruff for formatting generated artifacts and includes various documentation and cleanup improvements across the package. I have no feedback to provide on this pull request.

@olavloite olavloite added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Sep 15, 2026
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Sep 15, 2026
snapshot.py is generated from _async/snapshot.py, but the generated file
had picked up code the async source never had. Running the generator
deleted it. The drift came in via 25aba4f (PR #16488): a branch
authored before the CrossSync migration but merged after it, so it
edited snapshot.py as if that file were still hand-maintained.

Fixes:

- Port the _transaction_begin_event guard and the read()/execute_sql()
  docstrings back into _async/snapshot.py, so the generator reproduces
  them instead of dropping them.
- Use CrossSync.Lock / CrossSync.Event instead of raw threading, so the
  primitives survive the async -> sync conversion.
- De-duplicate the guard: read() and execute_sql() had identical copies,
  now one _wait_for_transaction_begin() helper.
- Async fix: read()/execute_sql() raised "Transaction has not begun."
  when a concurrent inline begin was in flight. They now wait for it,
  matching the sync client.
- generate.py: format with ruff instead of black. The repo uses ruff, so
  every run produced a formatting-only diff.
- generate.py: exit non-zero when given a file instead of a directory.
  It used to print "Generated 0 artifacts" and do nothing, which is how
  the drift went unnoticed.
- Delete snapshot_helpers.py, an orphaned generated file with a stale
  copy of execute_sql that nothing imports.
- Add tests for the guard, which had none.
- Speed up 4 tests that each waited out the real 30s begin timeout.
  They passed, just slowly; two were already slow on main. They now
  patch the timeout constant and assert the specific error message.
  Unit suite: 204s -> 57s.

Regenerating now leaves the tree unchanged:
  PYTHONPATH=.cross_sync python3 .cross_sync/generate.py \
    google/cloud/spanner_v1/_async/
  git diff --exit-code google/cloud/spanner_v1/
@olavloite
olavloite force-pushed the spanner-restore-cross-sync-parity branch from 27f2404 to e4797f5 Compare September 15, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants