I've played around with threading before in Python, but decided to give the asyncio
module a try, especially since you can cancel a running task, which seemed like a nice detail. However, for some reason, I can't wrap my head around it.
Here's what I wanted to implement (sorry if I'm using incorrect terminology):
- a
downloader
thread that downloads the same file every x seconds, checks its hash against the previous download and saves it if it's different. - a
webserver
thread that runs in the background, allowing control (pause, list, stop) of thedownloader
thread.
I used aiohttp
for the webserver.
This is what I have so far:
class aiotest():
def __init__(self):
self._dl = None # downloader future
self._webapp = None # web server future
self.init_server()
def init_server(self):
print('Setting up web interface')
app = web.Application()
app.router.add_route('GET', '/stop', self.stop)
print('added urls')
self._webapp = app
@asyncio.coroutine
def _downloader(self):
while True:
try:
print('Downloading and verifying file...')
# Dummy sleep - to be replaced by actual code
yield from asyncio.sleep(random.randint(3,10))
# Wait a predefined nr of seconds between downloads
yield from asyncio.sleep(30)
except asyncio.CancelledError:
break
@asyncio.coroutine
def _supervisor(self):
print('Starting downloader')
self._dl = asyncio.async(self._downloader())
def start(self):
loop = asyncio.get_event_loop()
loop.run_until_complete(self._supervisor())
loop.close()
@asyncio.coroutine
def stop(self):
print('Received STOP')
self._dl.cancel()
return web.Response(body=b"Stopping... ")
This class is called by:
t = aiotest()
t.start()
This doesn't work of course, and I feel that this is a horrible piece of code.
What's unclear to me:
- I stop the
downloader
in thestop()
method, but how would I go about stopping the webserver (e.g. in ashutdown()
method)? - Does the
downloader
need a new event loop, or can I use the loop returned byasyncio.get_event_loop()
? - Do I really need something like the
supervisor
for what I'm trying to implement? This seems so clunky. And how do I getsupervisor
to keep running instead of ending after a single execution as it does now?
One last, more general question: is asyncio
supposed to replace the threading
module (in the future)? Or does each have its own application?
I appreciate all the pointers, remarks and clarifications!