Search code examples
pythontornadopython-3.4

Tornado not running callback


This is very simple client for tcp-chat. This is main function:

@gen.coroutine
def main():
    factory = TCPClient()
    stream = yield factory.connect(af=socket.AF_INET, **options.options.group_dict("connect"))
    # Add notification callback
    ioloop.IOLoop.instance().add_callback(notification, stream)
    # Run application
    app = Application(stream)
    app.run()

if __name__ == '__main__':
    try:
        main()
        ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        pass

Application is running. App read data from console, send it into socket. Main loop of application:

@gen.coroutine
def run(self):
    while True:
        try:
            s = input('> ')
            command, text = self._parse_command(s)
            handler = self.handler(self._stream, self)
            yield handler.execute_command(command, text)
        except Exception as e:
            print(e)

And i have console notification. This function read response from socket and print into console:

@gen.coroutine
def notification(stream):
    message_length = yield stream.read_bytes(2)
    length = struct.unpack("!H", message_length)[0]
    message = yield stream.read_bytes(length)
    # request = Message.unpack(message=message)
    sys.stdout.write('\r'+' '*(len(readline.get_line_buffer())+2)+'\r')
    print(message)
    sys.stdout.write('> ' + readline.get_line_buffer())
    sys.stdout.flush()
    ioloop.IOLoop.instance().add_callback(notification, stream)

I add this function as callback into ioloop. But this function is never running. How run notification in background? Help my please...

UPD: I create new thread and run notification in new thread:

th = threading.Thread(target=notification, args=(self._stream, ))
th.run()

But it did not help...


Solution

  • input() is a blocking function; nothing else can happen while it is waiting for input. In order for the application to be responsive you must rework it to avoid blocking functions like input(), or to perform those functions on a separate thread.