Skip to content

backward compatibility is broken: module is not compatible with cartridge remote control #283

Closed
@olegrok

Description

@olegrok

After update to 0.12.0 some my tests started to fail with following backtrace:

self = <tarantool.connection.Connection object at 0x11b35aaa0>

    def connect(self):
        """
        Create a connection to the host and port specified on
        initialization. There is no need to call this method explicitly
        until you have set ``connect_now=False`` on initialization.
    
        :raise: :exc:`~tarantool.error.NetworkError`,
            :exc:`~tarantool.error.SslError`,
            :exc:`~tarantool.error.SchemaError`,
            :exc:`~tarantool.error.DatabaseError`
        """
    
        try:
            self.connect_basic()
            if self.transport == SSL_TRANSPORT:
                self.wrap_socket_ssl()
>           self.handshake()

/usr/local/lib/python3.10/site-packages/tarantool/connection.py:1039: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <tarantool.connection.Connection object at 0x11b35aaa0>

    def handshake(self):
        """
        Process greeting with Tarantool server.
    
        :raise: :exc:`~ValueError`,
            :exc:`~tarantool.error.NetworkError`
    
        :meta private:
        """
    
        greeting_buf = self._recv(IPROTO_GREETING_SIZE)
        greeting = greeting_decode(greeting_buf)
        if greeting.protocol != "Binary":
            raise NetworkError("Unsupported protocol: " + greeting.protocol)
        self.version_id = greeting.version_id
>       self._check_features()

/usr/local/lib/python3.10/site-packages/tarantool/connection.py:1017: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <tarantool.connection.Connection object at 0x11b35aaa0>

    def _check_features(self):
        """
        Execute an ID request: inform the server about the protocol
        version and features connector support and get server-side
        information about it.
    
        After executing this request, the connector will choose a
        protocol version and features supported both by connector and
        server.
    
        :raise: :exc:`~AssertionError`,
            :exc:`~tarantool.error.DatabaseError`,
            :exc:`~tarantool.error.SchemaError`,
            :exc:`~tarantool.error.NetworkError`,
            :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:
            ER_UNKNOWN_REQUEST_TYPE = 48
            if exc.code == ER_UNKNOWN_REQUEST_TYPE:
                server_protocol_version = None
                server_features = []
                server_auth_type = None
            else:
>               raise exc

/usr/local/lib/python3.10/site-packages/tarantool/connection.py:2149: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <tarantool.connection.Connection object at 0x11b35aaa0>

    def _check_features(self):
        """
        Execute an ID request: inform the server about the protocol
        version and features connector support and get server-side
        information about it.
    
        After executing this request, the connector will choose a
        protocol version and features supported both by connector and
        server.
    
        :raise: :exc:`~AssertionError`,
            :exc:`~tarantool.error.DatabaseError`,
            :exc:`~tarantool.error.SchemaError`,
            :exc:`~tarantool.error.NetworkError`,
            :exc:`~tarantool.error.SslError`
        """
    
        try:
            request = RequestProtocolVersion(self,
                                             CONNECTOR_IPROTO_VERSION,
                                             CONNECTOR_FEATURES)
>           response = self._send_request(request)

/usr/local/lib/python3.10/site-packages/tarantool/connection.py:2138: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <tarantool.connection.Connection object at 0x11b35aaa0>
request = <tarantool.request.RequestProtocolVersion object at 0x11b35b640>, on_push = None
on_push_ctx = None

    def _send_request(self, request, on_push=None, on_push_ctx=None):
        """
        Send a request to the server through the socket.
    
        :param request: Request to send.
        :type request: :class:`~tarantool.request.Request`
    
        :param on_push: Сallback for processing out-of-band messages.
        :type on_push: :obj:`function`, optional
    
        :param on_push_ctx: Сontext for working with on_push callback.
        :type on_push_ctx: optional
    
        :rtype: :class:`~tarantool.response.Response`
    
        :raise: :exc:`~AssertionError`,
            :exc:`~tarantool.error.DatabaseError`,
            :exc:`~tarantool.error.SchemaError`,
            :exc:`~tarantool.error.NetworkError`,
            :exc:`~tarantool.error.SslError`
    
        :meta private:
        """
        assert isinstance(request, Request)
    
        self._opt_reconnect()
    
>       return self._send_request_wo_reconnect(request, on_push, on_push_ctx)

/usr/local/lib/python3.10/site-packages/tarantool/connection.py:1249: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <tarantool.connection.Connection object at 0x11b35aaa0>
request = <tarantool.request.RequestProtocolVersion object at 0x11b35b640>, on_push = None
on_push_ctx = None

    def _send_request_wo_reconnect(self, request, on_push=None, on_push_ctx=None):
        """
        Send request without trying to reconnect.
        Reload schema, if required.
    
        :param request: Request to send.
        :type request: :class:`~tarantool.request.Request`
    
        :param on_push: Сallback for processing out-of-band messages.
        :type on_push: :obj:`function`, optional
    
        :param on_push_ctx: Сontext for working with on_push callback.
        :type on_push_ctx: optional
    
        :rtype: :class:`~tarantool.response.Response`
    
        :raise: :exc:`~AssertionError`,
            :exc:`~tarantool.error.SchemaError`,
            :exc:`~tarantool.error.NetworkError`
    
        :meta private:
        """
    
        assert isinstance(request, Request)
    
        response = None
        while True:
            try:
                self._socket.sendall(bytes(request))
>               response = request.response_class(self, self._read_response())

/usr/local/lib/python3.10/site-packages/tarantool/connection.py:1136: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <tarantool.connection.Connection object at 0x11b35aaa0>

    def _read_response(self):
        """
        Read response from the transport (socket).
    
        :return: Tuple of the form ``(header, body)``.
        :rtype: :obj:`tuple`
    
        :meta private:
        """
    
        # Read packet length
>       length = msgpack.unpackb(self._recv(5))

/usr/local/lib/python3.10/site-packages/tarantool/connection.py:1103: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <tarantool.connection.Connection object at 0x11b35aaa0>, to_read = 5

    def _recv(self, to_read):
        """
        Receive binary data from connection socket.
    
        :param to_read: Amount of data to read, in bytes.
        :type to_read: :obj:`int`
    
        :return: Buffer with read data
        :rtype: :obj:`bytes`
    
        :meta private:
        """
    
        buf = b""
        while to_read > 0:
            try:
                tmp = self._socket.recv(to_read)
            except OverflowError:
                self._socket.close()
                err = socket.error(
                    errno.ECONNRESET,
                    "Packet too large. Closing connection to server"
                )
                raise NetworkError(err)
            except socket.error:
                err = socket.error(
                    errno.ECONNRESET,
                    "Lost connection to server during query"
                )
                raise NetworkError(err)
            else:
                if len(tmp) == 0:
                    err = socket.error(
                        errno.ECONNRESET,
                        "Lost connection to server during query"
                    )
>                   raise NetworkError(err)
E                   tarantool.error.NetworkError: (54, 'Connection reset by peer')

/usr/local/lib/python3.10/site-packages/tarantool/connection.py:1087: NetworkError

tarantoolctl is able to connect to my instance. However tarantool-python is not.
Seems it happens because module now is not compatible with cartridge.remote-control (and probably some ancient Tarantool versions). There is workaround in cartridge code to make it compatible with netbox - tarantool/cartridge@1649b40 but seems these connector doesn't consider it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcustomer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions