asyncio - how to stop loop?

Discussion in 'Python' started by Frank Millman, Jun 11, 2014.

  1. Hi all

    I have a 'start.py' script that kicks off my program by starting a number of
    services.

    For now, I stop it by allowing the user to press <enter>, after which I
    close down the services and stop the program. (For production I imagine it
    would be better to run it in the background and send it some kind of signal
    to terminate, but for testing this suffices.)

    As one of the services is a 'listening' loop, which would normally prevent
    access to the keyboard, I start it in a separate thread. For example, when I
    was using cherrypy as the server, I had -

    server = cherrypy.wsgiserver.CherryPyWSGIServer((host, port),
    dispatcher)
    threading.Thread(target=server.start).start()
    input('Press <enter> to stop')
    server.stop()

    Now I am playing with asyncio, but I cannot get it to behave the same.

    Here are my attempts. I use python 3.4.1, and I tested on Windows and
    Linux - the results are different on each platform.

    First attempt - same as before

    loop = asyncio.get_event_loop()
    threading.Thread(target=loop.run_forever).start()
    input('Press <enter> to stop')
    loop.stop()
    loop.close()

    Windows traceback -

    Exception in thread Thread-1:
    Traceback (most recent call last):
    File "C:\Python34\lib\threading.py", line 920, in _bootstrap_inner
    self.run()
    File "C:\Python34\lib\threading.py", line 868, in run
    self._target(*self._args, **self._kwargs)
    File "C:\Python34\lib\asyncio\base_events.py", line 184, in run_forever
    self._run_once()
    File "C:\Python34\lib\asyncio\base_events.py", line 795, in _run_once
    event_list = self._selector.select(timeout)
    AttributeError: 'NoneType' object has no attribute 'select'

    With Linux, it does not terminate. If I press Ctrl_C, I get this traceback
    (hope there are no typos) -

    Traceback (most recent call last):
    File "/usr/local/lib/python3.4/threading.py", line 1294, in _shutdown
    t.join()
    File "/usr/local/lib/python3.4/threading.py", line 1060, in join
    self._wait_for_tstate_lock()
    File "/usr/local/lib/python3.4/threading.py", line 1076, in
    _wait_for_tstate_lock
    elif lock.acquire(block, timeout):
    KeyboardInterrupt


    Second attempt - move the keyboard input to a separate thread

    def stop_loop():
    input('Press <enter> to stop')
    loop.stop()
    loop.close()

    loop = asyncio.get_event_loop()
    threading.Thread(target=stop_loop).start()
    loop.run_forever()

    With Windows, it works - the program closes cleanly.

    With Linux, it does not terminate. If I press Ctrl_C, I get this traceback
    (hope there are no typos) -

    Traceback (most recent call last):
    File "test_async.py", line 20, in <module>
    loop.run_forever()
    File "/usr/local/lib/python3.4/asyncio.base_events.py", line 184, in
    run_forever
    self._run_once()
    File "/usr/local/lib/python3.4/asyncio.base_events.py", line 795, in
    _run_once
    event_list = self._selector.select(timeout)
    File "/usr/local/lib/python3.4/asyncio.selectors.py", line 424, in select
    fd_event_list = self._epoll.poll(timeout, max_cv)
    KeyboardInterrupt


    Third attempt - get the loop to close itself (cannot use in practice, but
    see what happens)

    def stop_loop():
    loop.stop()
    loop.close()

    loop = asyncio.get_event_loop()
    loop.call_later(2, stop_loop)
    loop.run_forever()

    Both platforms show the same traceback, after two seconds -

    Traceback (most recent call last):
    File "C:\Documents and Settings\frank\aib\aib_async\test_async.py", line
    29, in <module>
    loop.run_forever()
    File "C:\Python34\lib\asyncio\base_events.py", line 184, in run_forever
    self._run_once()
    File "C:\Python34\lib\asyncio\base_events.py", line 795, in _run_once
    event_list = self._selector.select(timeout)
    AttributeError: 'NoneType' object has no attribute 'select'

    Can anyone suggest a way to get the loop to stop cleanly?

    Thanks

    Frank Millman
     
    Frank Millman, Jun 11, 2014
    #1
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.