Skip to content

perf(spanner): add fast-path for multiplexed session acquisition - #18317

Merged
olavloite merged 1 commit into
mainfrom
spanner-fast-path-mux-session-acquisition
Sep 10, 2026
Merged

perf(spanner): add fast-path for multiplexed session acquisition#18317
olavloite merged 1 commit into
mainfrom
spanner-fast-path-mux-session-acquisition

Conversation

@olavloite

@olavloite olavloite commented Sep 9, 2026

Copy link
Copy Markdown
Contributor
  • Bypass initialization and multiplexed session locks on steady-state queries.
  • Build replacement sessions outside the lock during maintenance rotation, holding the lock only for the pointer swap.
  • Replace maintenance sleep loops with event wait for immediate shutdown termination.
  • Use monotonic time for maintenance intervals and clear local manager references before waiting.

Results Summary

Metric PR #18317 (spanner-fast-path-mux-session-acquisition) 7-Day Nightly Baseline (main) Delta Absolute Difference
Sample Count 628,791 ops 300,566,193 ops
Mean Latency 5.327 ms 5.344 ms -0.32% -0.017 ms (-17 us)
P50 Latency 4.962 ms 4.996 ms -0.68% -0.034 ms (-34 us)
P90 Latency 6.624 ms 6.769 ms -2.15% -0.145 ms (-145 us)
P99 Latency 11.068 ms 10.700 ms +3.44% +0.368 ms

The performance gain from this optimization is minimal in an end-to-end test.

@olavloite
olavloite requested a review from a team as a code owner September 9, 2026 10:59

@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 refactors multiplexed session management in both the synchronous and asynchronous database session managers. Key changes include introducing a fast path for retrieving already-initialized multiplexed sessions, replacing time.time() with time.monotonic() for interval calculations, implementing a safer session rotation mechanism (_rotate_multiplexed_session) that swaps sessions before deletion, and using event-based waiting for cleaner termination. Extensive unit tests have been added to cover these changes. The review feedback highlights multiple violations of the Repository Style Guide (Section 4: Unit Testing and Mock Hygiene) where time.monotonic is patched globally in the tests. To ensure test isolation, these mocks should be localized to the target module's import path.

Comment thread packages/google-cloud-spanner/tests/unit/_async/test_sessions_manager_extra.py Outdated
Comment thread packages/google-cloud-spanner/tests/unit/_async/test_sessions_manager_extra.py Outdated
Comment thread packages/google-cloud-spanner/tests/unit/_async/test_sessions_manager_extra.py Outdated
Comment thread packages/google-cloud-spanner/tests/unit/test_database_session_manager.py Outdated
Comment thread packages/google-cloud-spanner/tests/unit/test_database_session_manager.py Outdated
Comment thread packages/google-cloud-spanner/tests/unit/test_database_session_manager.py Outdated
Comment thread packages/google-cloud-spanner/tests/unit/test_database_session_manager.py Outdated
- Bypass initialization and multiplexed session locks on steady-state queries.
- Build replacement sessions outside the lock during maintenance rotation, holding the lock only for the pointer swap.
- Replace maintenance sleep loops with event wait for immediate shutdown termination.
- Use monotonic time for maintenance intervals and clear local manager references before waiting.
@olavloite
olavloite force-pushed the spanner-fast-path-mux-session-acquisition branch from 1b8b33e to 7bf0dcb Compare September 9, 2026 11:34
@olavloite

Copy link
Copy Markdown
Contributor Author

/gemini review

@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 refactors the multiplexed session management in both the synchronous and asynchronous database session managers. Key changes include adding a fast path in _get_multiplexed_session to return an existing session without locking, improving thread safety by assigning sessions and maintenance threads to local variables before updating instance state, introducing a _rotate_multiplexed_session helper to safely swap and delete sessions, and replacing the polling sleep in _maintain_multiplexed_session with an event-wait mechanism using time.monotonic(). Additionally, comprehensive unit tests have been added to verify these new behaviors and edge cases. No review comments were provided, so there is no feedback to address.

await self._multiplexed_session.delete()
session_to_delete = self._multiplexed_session
self._multiplexed_session = None
await session_to_delete.delete()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Note: This is strictly speaking a bug. Multiplexed sessions cannot be deleted. I will fix this in a separate follow-up pull request. I kept it for now to keep the change as small as possible.

Comment on lines -144 to +149
self._multiplexed_session_thread.start()
maintenance_thread.start()
self._multiplexed_session_thread = maintenance_thread
self._multiplexed_session = session

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.

Assume if maintenance_thread.start() fails, now the local session gets orphaned on the Spanner backend because self._multiplexed_session isn't updated until like 149. I believe this opens a scope for session leaks.

Old code assigned it immediately after creation, ensuring close() can always clean it up if things go wrong.

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.

Just noticed from your other comment that multiplexed sessions cannot be deleted. We should be good here then.

@olavloite
olavloite merged commit 9569b39 into main Sep 10, 2026
47 checks passed
@olavloite
olavloite deleted the spanner-fast-path-mux-session-acquisition branch September 10, 2026 14:59
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