I wrote a simple tcp server using gevent.StreamServerfor testing. To send responses to some clients, I need a non-blocking way to handle input through raw_input(), preferably without using threads.
After some googling, I stumbled upon this question: How to do non-blocking raw_input when using eventlet.monkey_patch () and why does it block everything even when executed in another thread?
I wrote the following, and he does exactly what I want, but I guess it is better to approach him. Can someone point me in the right direction? The idea of why try / except does not catch KeyboardInterrupt is also evaluated.
import select
from gevent.monkey import patch_all
from gevent.server import StreamServer
patch_all(os=True, select=True)
def raw_input(message):
""" Non-blocking input from stdin. """
sys.stdout.write(message)
select.select([sys.stdin], [], [])
return sys.stdin.readline()
def main():
""" Run the server, listen for commands """
server = StreamServer(("0.0.0.0", 6000), handle)
print "Starting server"
gevent.signal(signal.SIGTERM, server.close)
gevent.signal(signal.SIGQUIT, server.close)
gevent.signal(signal.SIGINT, server.close)
server.start()
while True:
try:
a = raw_input("")
if a:
print "Received %s" % a
gevent.sleep(0)
except KeyboardInterrupt:
print "Received a shutdown signal, going down ..."
server.stop()
sys.exit(0)
if __name__ == "__main__":
main()
EDIT: , main(). , - , .
from gevent.signal import signal
def get_console_input():
""" Non-blocking console input to the server """
select.select([sys.stdin], [], [])
return sys.stdin.readline()
def exit(server):
""" Quit the server gracefully """
print "Received shutdown signal, going down. """
server.close()
sys.exit(0)
def main():
""" The main function. Create and run the server, listen for commands and
append any command to the server so it can send them on to the clients """
server = MyServer(("0.0.0.0", PORT))
print "Starting server"
gevent.signal(signal.SIGTERM, exit, server)
gevent.signal(signal.SIGQUIT, exit, server)
gevent.signal(signal.SIGINT, exit, server)
server.start()
while True:
get_console_input()
gevent.sleep(0)
if __name__ == "__main__":
main()