sockets - python asyncio run event loop once? -


i trying understand asyncio library, using sockets. have written code in attempt gain understanding,

i wanted run sender , receiver sockets asynchrounously. got point data sent till last one, have run 1 more loop. looking @ how this, found this link stackoverflow, implemented below -- going on here? there better/more sane way call stop followed run_forever?

the documentation stop() in event loop is:

stop running event loop.

every callback scheduled before stop() called run. callbacks scheduled after stop() called not run. however, callbacks run if run_forever() called again later.

and run_forever()'s documentation is:

run until stop() called.

questions:

  • why in world run_forever way run_once? doesn't make sense
  • is there better way this?
  • does code reasonable way program asyncio library?
  • is there better way add tasks event loop besides asyncio.async()? loop.create_task gives error on linux system.

https://gist.github.com/cloudformdesign/b30e0860497f19bd6596

the stop(); run_forever() trick works because of how stop implemented:

def stop(self):     """stop running event loop.      every callback scheduled before stop() called run.     callback scheduled after stop() called won't.  however,     callbacks run if run() called again later.     """     self.call_soon(_raise_stop_error)  def _raise_stop_error(*args):     raise _stoperror 

so, next time event loop runs , executes pending callbacks, it's going call _raise_stop_error, raises _stoperror. run_forever loop break on specific exception:

def run_forever(self):     """run until stop() called."""     if self._running:         raise runtimeerror('event loop running.')     self._running = true     try:         while true:             try:                 self._run_once()             except _stoperror:                 break     finally:         self._running = false 

so, scheduling stop() , calling run_forever, end running 1 iteration of event loop, stopping once hits _raise_stop_error callback. may have noticed _run_once defined , called run_forever. call directly, can block if there aren't callbacks ready run, may not desirable. don't think there's cleaner way - answer provided andrew svetlov, asyncio contributor; know if there's better option. :)

in general, code looks reasonable, though think shouldn't using run_once approach begin with. it's not deterministic; if had longer list or slower system, might require more 2 iterations print everything. instead, should send sentinel tells receiver shut down, , wait on both send , receive coroutines finish:

import sys import time import socket import asyncio   addr = ('127.0.0.1', 1064) sentinel = b"_done_"   # ... (this stuff same)  @asyncio.coroutine def sending(addr, dataiter):     loop = asyncio.get_event_loop()     d in dataiter:         print("sending:", d)         sock = socket.socket()         yield send_close(loop, sock, addr, str(d).encode())     # send sentinel     sock = socket.socket()     yield send_close(loop, sock, addr, sentinel)  @asyncio.coroutine def receiving(addr):     loop = asyncio.get_event_loop()     sock = socket.socket()     try:         sock.setblocking(false)         sock.bind(addr)         sock.listen(5)          while true:             data = yield accept_recv(loop, sock)             if data == sentinel:  # got sentinel                 return             print("recevied:", data)     finally: sock.close()  def main():     loop = asyncio.get_event_loop()     # add these items event loop     recv = asyncio.async(receiving(addr), loop=loop)     send = asyncio.async(sending(addr, range(10)), loop=loop)     loop.run_until_complete(asyncio.wait([recv, send]))  main() 

finally, asyncio.async right way add tasks event loop. create_task added in python 3.4.2, if have earlier version won't exist.


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -