Skip to content

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

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

Closed
olegrok opened this issue Feb 26, 2023 · 0 comments · Fixed by #284
Closed
Labels
bug Something isn't working customer

Comments

@olegrok
Copy link
Contributor

olegrok commented Feb 26, 2023

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.

@olegrok olegrok added bug Something isn't working customer labels Feb 26, 2023
olegrok added a commit to olegrok/tarantool-python that referenced this issue Feb 27, 2023
"IProto features" are available since Tarantool 2.10 and there is
no need to even try to fetch them for lower versions.
Such check there is in netbox code [1].
Before this patch cartridge remote control closed the connection
after RequestProtocolVersion however but for netbox it worked
fine.
So let's uniform behaviour between connectors adding a small check
to skip request if there is a gurarntee that "IProto features" are
not supported.

Closes tarantool#283

[1] tarantool/tarantool@2cbec82#diff-a47383908beda20a06c9f64bf5c3d4c51879034e38bcdccdf45210e89ce6dfb7R1947
olegrok added a commit to olegrok/tarantool-python that referenced this issue Feb 27, 2023
"IProto features" are available since Tarantool 2.10 and there is
no need to even try to fetch them for lower versions.
Such check there is in netbox code [1].
Before this patch cartridge remote control closed the connection
after RequestProtocolVersion however but for netbox it worked
fine.
So let's uniform behaviour between connectors adding a small check
to skip request if there is a gurarntee that "IProto features" are
not supported.

Closes tarantool#283

[1] tarantool/tarantool@2cbec82#diff-a47383908beda20a06c9f64bf5c3d4c51879034e38bcdccdf45210e89ce6dfb7R1947
olegrok added a commit to olegrok/tarantool-python that referenced this issue Feb 27, 2023
"IProto features" are available since Tarantool 2.10 and there is
no need to even try to fetch them for lower versions.
Such check there is in netbox code [1].
Before this patch cartridge remote control closed the connection
after RequestProtocolVersion however but for netbox it worked
fine.
So let's uniform behaviour between connectors adding a small check
to skip request if there is a gurarntee that "IProto features" are
not supported.

Closes tarantool#283

[1] tarantool/tarantool@2cbec82#diff-a47383908beda20a06c9f64bf5c3d4c51879034e38bcdccdf45210e89ce6dfb7R1947
DifferentialOrange pushed a commit that referenced this issue Feb 27, 2023
"IProto features" are available since Tarantool 2.10 and there is
no need to even try to fetch them for lower versions.
Such check there is in netbox code [1].
Before this patch cartridge remote control closed the connection
after RequestProtocolVersion however but for netbox it worked
fine.
So let's uniform behaviour between connectors adding a small check
to skip request if there is a gurarntee that "IProto features" are
not supported.

Closes #283

[1] tarantool/tarantool@2cbec82#diff-a47383908beda20a06c9f64bf5c3d4c51879034e38bcdccdf45210e89ce6dfb7R1947
DifferentialOrange added a commit that referenced this issue Feb 28, 2023
Overview

  This release introduces several bug fixes and behavior improvements.

Breaking changes

  This release should not break any existing behavior.

Bugfixes
  - Discovery iproto features only for Tarantools since version
    2.10.0 (#283).
  - Schema fetch for spaces with foreign keys (#282).
DifferentialOrange added a commit that referenced this issue Feb 28, 2023
Overview

  This release introduces several bug fixes and behavior improvements.

Breaking changes

  This release should not break any existing behavior.

Bugfixes
  - Discovery iproto features only for Tarantools since version
    2.10.0 (#283).
  - Schema fetch for spaces with foreign keys (#282).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working customer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant