asyncio - how to stop loop?


F

Frank Millman

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
 
Ad

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. After that, you can post your question and our members will help you out.

Ask a Question

Top