-
Notifications
You must be signed in to change notification settings - Fork 50
Fix TokenAwarePolicy to call child.make_query_plan once #634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
@copilot please complete the work on this PR. |
Co-authored-by: mykaul <4655593+mykaul@users.noreply.github.com>
Completed! The optimization ensures Summary of changes:
|
|
@copilot address review comments from your friendly AI codeQL above. |
Co-authored-by: mykaul <4655593+mykaul@users.noreply.github.com>
Co-authored-by: mykaul <4655593+mykaul@users.noreply.github.com>
Addressed the memory usage concern from the code review. See commits ec8203e and 85c6ee8. Changes made:
All 83 tests pass and no security issues detected. |
cassandra/policies.py
Outdated
| child_plan = list(child.make_query_plan(keyspace, query)) | ||
|
|
||
| replicas = [] | ||
| if self._cluster_metadata._tablets.table_has_tablets(keyspace, query.table): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot - this line (if self._cluster_metadata._tablets.table_has_tablets(keyspace, query.table):) could be replaced with the next line (tablet = ...) and then if tablet is not None: that we have already. Can you create a follow-up commit with this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. The table_has_tablets check has been replaced with a direct call to get_tablet_for_key, followed by the existing if tablet is not None check. This simplifies the code since get_tablet_for_key already returns None when there are no tablets for the table. See commit d49f4dd.
…ts call Co-authored-by: mykaul <4655593+mykaul@users.noreply.github.com>
| keyspace = 'keyspace' | ||
| routing_key = 'routing_key' | ||
| query = Statement(routing_key=routing_key, keyspace=keyspace) | ||
| qplan = list(policy.make_query_plan(keyspace, query)) |
| # Test case 2: Without routing key (should call once) | ||
| child_policy.reset_mock() | ||
| query = Statement(routing_key=None, keyspace=keyspace) | ||
| qplan = list(policy.make_query_plan(keyspace, query)) |
| # Test case 3: Without keyspace (should call once) | ||
| child_policy.reset_mock() | ||
| query = Statement(routing_key=routing_key, keyspace=None) | ||
| qplan = list(policy.make_query_plan(None, query)) |
|
|
||
| child_policy.reset_mock() | ||
| query = Statement(routing_key=routing_key, keyspace=keyspace, table='test_table') | ||
| qplan = list(policy.make_query_plan(keyspace, query)) |
Pre-review checklist
./docs/source/.Description
Optimizes
TokenAwarePolicy.make_query_planto callchild.make_query_planonly once instead of up to 3 times in some scenarios, improving performance by eliminating redundant query plan generation while preserving memory efficiency through lazy evaluation. Also simplifies the tablet routing logic by removing redundant checks.Problem
In the original implementation,
TokenAwarePolicy.make_query_plancould callchild.make_query_planup to three times:This redundant computation was unnecessary and could impact performance, especially with complex child policies. Additionally, the tablet routing code had a redundant
table_has_tabletscheck before callingget_tablet_for_key.Changes Made
cassandra/policies.py
TokenAwarePolicy.make_query_planto callchild.make_query_planonly oncechild.make_query_planonce and convert to list for reuse (needed for replica identification and yielding remaining hosts)table_has_tabletscheck - now directly callsget_tablet_for_keyand checks if the result is not None (sinceget_tablet_for_keyalready returns None when there are no tablets)tests/unit/test_policies.py
test_child_make_query_plan_called_oncethat validates the optimization works in all scenarios:_assert_shuffleto expect one call for both tablet and vnode scenariosget_tablet_for_key.return_valueinstead of the removedtable_has_tablets.return_valuePerformance & Memory Impact
child.make_query_planin worst-case scenarioschild.make_query_planTesting
tests/unit/test_policies.pypassOriginal prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.