You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tinkerpop.apache.org by "Steve Kieffer (Jira)" <ji...@apache.org> on 2022/06/10 14:16:00 UTC

[jira] [Created] (TINKERPOP-2752) `AiohttpTransport` malfunctions in an eventlet monkey patched app

Steve Kieffer created TINKERPOP-2752:
----------------------------------------

             Summary: `AiohttpTransport` malfunctions in an eventlet monkey patched app
                 Key: TINKERPOP-2752
                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2752
             Project: TinkerPop
          Issue Type: Bug
          Components: python
    Affects Versions: 3.5.2, 3.6.0
         Environment: python 3.8, running both natively on macOS, and within a Docker container hosted on macOS
            Reporter: Steve Kieffer


I'm running an eventlet-based Flask web app, that starts out with a call to
{code:python}
eventlet.monkey_patch()
{code}
and has view functions that use gremlin-python to connect to a gremlin server.

I've found that if the browser issues several requests in rapid succession, it can provoke the
{code:python}
RuntimeError: Cannot run the event loop while another loop is running
{code}
error. Passing
{code:python}
call_from_event_loop=True
{code}
when constructing the {{DriverRemoteConnection}} just leads to a different type of error, because the problem is transient, not consistent.

I've developed a minimal example that demonstrates the issue, and can share a link to that if it would be helpful.

*Possible solution:*

How about supplying another transport, besides the {{AiohttpTransport}} class, which uses the {{websocket-client}} python package, instead of {{aiohttp}}?

I've made one which is very rudimentary but, in testing so far, works fine and solves this issue:
{code:python}
from gremlin_python.driver.transport import AbstractBaseTransport
import websocket


class WebsocketTransport(AbstractBaseTransport):

    def __init__(self, **kwargs):
        self.ws = websocket.WebSocket(**kwargs)

    def connect(self, url, headers=None):
        headers = headers or []
        self.ws.connect(url, header=headers)

    def write(self, message):
        self.ws.send_binary(message)

    def read(self):
        return self.ws.recv()

    def close(self):
        self.ws.close()

    @property
    def closed(self):
        return not self.ws.connected


def transport_factory():
    return WebsocketTransport()
{code}
Happy to open this as a PR, if it seems like a good idea.



--
This message was sent by Atlassian Jira
(v8.20.7#820007)