From 8a093c6124c4b580491c6ba9e5297daed60cb2db Mon Sep 17 00:00:00 2001 From: Georgy Moiseev Date: Tue, 27 Jun 2023 15:43:53 +0300 Subject: [PATCH] conn: store client and server protocol info Store client and server protocol version and features in connection object, similar to go-tarantool [1]. Before the patch, we stored only products: minimal protocol version of server and client and the list of features supported both by client and server. 1. https://github.com/tarantool/go-tarantool/pull/226 Part of #267 --- tarantool/connection.py | 49 +++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/tarantool/connection.py b/tarantool/connection.py index 9e0ec0f9..b6e8355a 100644 --- a/tarantool/connection.py +++ b/tarantool/connection.py @@ -20,6 +20,7 @@ import ctypes.util from ctypes import c_ssize_t from typing import Optional, Union +from copy import copy import msgpack @@ -838,6 +839,10 @@ def __init__(self, host, port, self.version_id = None self.uuid = None self._salt = None + self._client_protocol_version = CONNECTOR_IPROTO_VERSION + self._client_features = copy(CONNECTOR_FEATURES) + self._server_protocol_version = None + self._server_features = None if connect_now: self.connect() @@ -1044,10 +1049,11 @@ def handshake(self): if greeting.protocol != "Binary": raise NetworkError("Unsupported protocol: " + greeting.protocol) self.version_id = greeting.version_id - if self.version_id >= version_id(2, 10, 0): - self._check_features() self.uuid = greeting.uuid self._salt = greeting.salt + + self._check_features() + if self.user: self.authenticate(self.user, self.password) @@ -2057,33 +2063,28 @@ def _check_features(self): :exc:`~tarantool.error.SslError` """ - try: - request = RequestProtocolVersion(self, - CONNECTOR_IPROTO_VERSION, - CONNECTOR_FEATURES) - response = self._send_request(request) - server_protocol_version = response.protocol_version - server_features = response.features - server_auth_type = response.auth_type - except DatabaseError as exc: - if exc.code == ER_UNKNOWN_REQUEST_TYPE: - server_protocol_version = None - server_features = [] - server_auth_type = None - else: - raise exc - - if server_protocol_version is not None: - self._protocol_version = min(server_protocol_version, - CONNECTOR_IPROTO_VERSION) + if self.version_id >= version_id(2, 10, 0): + try: + request = RequestProtocolVersion(self, + self._client_protocol_version, + self._client_features) + response = self._send_request(request) + self._server_protocol_version = response.protocol_version + self._server_features = response.features + self._server_auth_type = response.auth_type + except DatabaseError as exc: + if exc.code != ER_UNKNOWN_REQUEST_TYPE: + raise exc + + if self._server_protocol_version is not None: + self._protocol_version = min(self._server_protocol_version, + self._client_protocol_version) # Intercept lists of features - features_list = [val for val in CONNECTOR_FEATURES if val in server_features] + features_list = [val for val in self._client_features if val in self._server_features] for val in features_list: self._features[val] = True - self._server_auth_type = server_auth_type - def _packer_factory(self): return self._packer_factory_impl(self)