Skip to content
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

add_reader not functioning the same as asyncio version #97

Closed
kura opened this issue Jun 22, 2017 · 7 comments
Closed

add_reader not functioning the same as asyncio version #97

kura opened this issue Jun 22, 2017 · 7 comments

Comments

@kura
Copy link

kura commented Jun 22, 2017

  • uvloop version: 0.8.0
  • Python version: 3.6.1
  • Platform: Debian 9
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env?: yes

I lifted a threaded controller from another project to use during testing.

class Controller:

    def __init__(self, sock=None, loop=None):
        if sock is not None:
            self.sock = sock
        else:
            self.sock = _socket('127.0.0.1', 0, socket.AF_INET)
        self.server = None
        self.loop = asyncio.new_event_loop() if loop is None else loop
        self.thread = None
        self._rsock, self._wsock = socket.socketpair()
        self.loop.add_reader(self._rsock, self._reader)

    def _reader(self):
        self.loop.remove_reader(self._rsock)
        self.loop.stop()
        for task in asyncio.Task.all_tasks(self.loop):
            task.cancel()
        self._rsock.close()
        self._wsock.close()

    def _run(self, ready_event):
        asyncio.set_event_loop(self.loop)
        conf = Config(None)
        conf.mailname = 'blackhole.io'
        _server = self.loop.create_server(lambda: Smtp([]),
                                          sock=self.sock)
        self.server = self.loop.run_until_complete(_server)
        self.loop.call_soon(ready_event.set)
        self.loop.run_forever()
        self.server.close()
        self.loop.run_until_complete(self.server.wait_closed())
        self.sock.close()
        self.loop.close()

    def start(self):
        ready_event = threading.Event()
        self.thread = threading.Thread(target=self._run, args=(ready_event, ))
        self.thread.daemon = True
        self.thread.start()
        ready_event.wait()

    def stop(self):
        self._wsock.send(b'x')
        self.thread.join()

The line self.loop.add_reader(self._rsock, self._reader) fails because uvloop's add_reader expects the first argument to be a file descriptor whereas asyncio allows a socket to be passed, in this case from socket.socketpair().

I have since updated this piece of code to remove using a socket to kill the thread after testing is complete.

@1st1
Copy link
Member

1st1 commented Jun 27, 2017

Interesting. I think some code in asyncio needs to be fixed too :)

@1st1
Copy link
Member

1st1 commented Jun 27, 2017

Specifically, asyncio code expects that fd is an int, not a file-like object. Everything works by accident because selector module supports both.

@kura
Copy link
Author

kura commented Jun 27, 2017

Cool! Well, that would totally explain it. You OK to copy this issue to CPython issues?

@1st1
Copy link
Member

1st1 commented Jun 27, 2017

Let me experiment with this a bit more to confirm that we need to fix anything in asyncio. I just did a cursory look.

@kura
Copy link
Author

kura commented Jun 27, 2017

Rgr that.

1st1 added a commit that referenced this issue Nov 10, 2017
Fixes issue #97.
More elaborate version of PR #101.  test_socket_fileno by @minrk.
@1st1
Copy link
Member

1st1 commented Nov 13, 2017

Fixed in master. Will be in the next release 0.9.0 soon

@1st1 1st1 closed this as completed Nov 13, 2017
@1st1
Copy link
Member

1st1 commented Nov 27, 2017

0.9.0 is available now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants