Im trying to make non-blocking console for network client with asyncio.
import sys
import select
import tty
import termios
import asyncio
def isData():
return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])
@asyncio.coroutine
def load():
n = 0
while True:
print(n)
n += 1
yield from asyncio.sleep(1)
@asyncio.coroutine
def get_input():
old_settings = termios.tcgetattr(sys.stdin)
try:
tty.setcbreak(sys.stdin.fileno())
while True:
if isData():
c = sys.stdin.read(1)
print(c)
if c == '\x1b':
break
if c == '\x0a':
print('Enter pressed')
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
loop = asyncio.get_event_loop()
asyncio.ensure_future(load())
asyncio.ensure_future(get_input())
loop.run_forever()
load() is simulates some coroutine. It will be replaced with communication with server.
So, non-blocking input was made with get_input(). It works well alone, but for some reason it blocks execution of load(). Looks like its because of c = sys.stdin.read(1)
Can I make it like
data = yield from asyncio.wait_for(client_reader.readline(), timeout=TIMEOUT)
I use to read data from server.
Or maybe where is straightforward way to make non-blocking console with asyncio?
UPDATE: possible solution:
@asyncio.coroutine
def get_input():
old_settings = termios.tcgetattr(sys.stdin)
try:
tty.setcbreak(sys.stdin.fileno())
while True:
check = yield from loop.run_in_executor(None, isData)
if check:
c = sys.stdin.read(1)
print(c)
if c == '\x1b':
break
if c == '\x0a':
print('Enter pressed')
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)