|
41 | 41 | import weakref
|
42 | 42 | from weakref import WeakValueDictionary
|
43 | 43 |
|
44 |
| -from cassandra import (ConsistencyLevel, AuthenticationFailed, |
| 44 | +from cassandra import (ConsistencyLevel, AuthenticationFailed, InvalidRequest, |
45 | 45 | OperationTimedOut, UnsupportedOperation,
|
46 | 46 | SchemaTargetType, DriverException, ProtocolVersion,
|
47 | 47 | UnresolvableContactPoints)
|
|
51 | 51 | EndPoint, DefaultEndPoint, DefaultEndPointFactory,
|
52 | 52 | ContinuousPagingState, SniEndPointFactory, ConnectionBusy)
|
53 | 53 | from cassandra.cqltypes import UserType
|
| 54 | +import cassandra.cqltypes as types |
54 | 55 | from cassandra.encoder import Encoder
|
55 | 56 | from cassandra.protocol import (QueryMessage, ResultMessage,
|
56 | 57 | ErrorMessage, ReadTimeoutErrorMessage,
|
|
79 | 80 | named_tuple_factory, dict_factory, tuple_factory, FETCH_SIZE_UNSET,
|
80 | 81 | HostTargetingStatement)
|
81 | 82 | from cassandra.marshal import int64_pack
|
| 83 | +from cassandra.tablets import Tablet, Tablets |
82 | 84 | from cassandra.timestamps import MonotonicTimestampGenerator
|
83 | 85 | from cassandra.compat import Mapping
|
84 | 86 | from cassandra.util import _resolve_contact_points_to_string_map, Version
|
@@ -1397,6 +1399,8 @@ def __init__(self,
|
1397 | 1399 | schema_metadata_enabled, token_metadata_enabled,
|
1398 | 1400 | schema_meta_page_size=schema_metadata_page_size)
|
1399 | 1401 |
|
| 1402 | + self._init_tablets() |
| 1403 | + |
1400 | 1404 | if client_id is None:
|
1401 | 1405 | self.client_id = uuid.uuid4()
|
1402 | 1406 | if application_name is not None:
|
@@ -2388,7 +2392,10 @@ def _prepare_all_queries(self, host):
|
2388 | 2392 | def add_prepared(self, query_id, prepared_statement):
|
2389 | 2393 | with self._prepared_statement_lock:
|
2390 | 2394 | self._prepared_statements[query_id] = prepared_statement
|
2391 |
| - |
| 2395 | + |
| 2396 | + # Experimental, this interface and use may change |
| 2397 | + def _init_tablets(self): |
| 2398 | + self.metadata._tablets = Tablets({}) |
2392 | 2399 |
|
2393 | 2400 | class Session(object):
|
2394 | 2401 | """
|
@@ -3541,6 +3548,7 @@ class PeersQueryType(object):
|
3541 | 3548 | _schema_meta_page_size = 1000
|
3542 | 3549 |
|
3543 | 3550 | _uses_peers_v2 = True
|
| 3551 | + _tablets_routing_v1 = False |
3544 | 3552 |
|
3545 | 3553 | # for testing purposes
|
3546 | 3554 | _time = time
|
@@ -3674,6 +3682,8 @@ def _try_connect(self, host):
|
3674 | 3682 | # If sharding information is available, it's a ScyllaDB cluster, so do not use peers_v2 table.
|
3675 | 3683 | if connection.features.sharding_info is not None:
|
3676 | 3684 | self._uses_peers_v2 = False
|
| 3685 | + |
| 3686 | + self._tablets_routing_v1 = connection.features.tablets_routing_v1 |
3677 | 3687 |
|
3678 | 3688 | # use weak references in both directions
|
3679 | 3689 | # _clear_watcher will be called when this ControlConnection is about to be finalized
|
@@ -4600,7 +4610,10 @@ def _query(self, host, message=None, cb=None):
|
4600 | 4610 | connection = None
|
4601 | 4611 | try:
|
4602 | 4612 | # TODO get connectTimeout from cluster settings
|
4603 |
| - connection, request_id = pool.borrow_connection(timeout=2.0, routing_key=self.query.routing_key if self.query else None) |
| 4613 | + if self.query: |
| 4614 | + connection, request_id = pool.borrow_connection(timeout=2.0, routing_key=self.query.routing_key, keyspace=self.query.keyspace, table=self.query.table) |
| 4615 | + else: |
| 4616 | + connection, request_id = pool.borrow_connection(timeout=2.0) |
4604 | 4617 | self._connection = connection
|
4605 | 4618 | result_meta = self.prepared_statement.result_metadata if self.prepared_statement else []
|
4606 | 4619 |
|
@@ -4719,6 +4732,19 @@ def _set_result(self, host, connection, pool, response):
|
4719 | 4732 | self._warnings = getattr(response, 'warnings', None)
|
4720 | 4733 | self._custom_payload = getattr(response, 'custom_payload', None)
|
4721 | 4734 |
|
| 4735 | + if self._custom_payload and self.session.cluster.control_connection._tablets_routing_v1 and 'tablets-routing-v1' in self._custom_payload: |
| 4736 | + protocol = self.session.cluster.protocol_version |
| 4737 | + info = self._custom_payload.get('tablets-routing-v1') |
| 4738 | + ctype = types.lookup_casstype('TupleType(LongType, LongType, ListType(TupleType(UUIDType, Int32Type)))') |
| 4739 | + tablet_routing_info = ctype.from_binary(info, protocol) |
| 4740 | + first_token = tablet_routing_info[0] |
| 4741 | + last_token = tablet_routing_info[1] |
| 4742 | + tablet_replicas = tablet_routing_info[2] |
| 4743 | + tablet = Tablet.from_row(first_token, last_token, tablet_replicas) |
| 4744 | + keyspace = self.query.keyspace |
| 4745 | + table = self.query.table |
| 4746 | + self.session.cluster.metadata._tablets.add_tablet(keyspace, table, tablet) |
| 4747 | + |
4722 | 4748 | if isinstance(response, ResultMessage):
|
4723 | 4749 | if response.kind == RESULT_KIND_SET_KEYSPACE:
|
4724 | 4750 | session = getattr(self, 'session', None)
|
|
0 commit comments