2015-10-08 2 views
0

Иногда я хочу, чтобы интерактивные пользователи отображали логику в сопроводительных документах торнадо. Эти пользователи часто нажимают Ctrl-C для прерывания длительных вычислений. Это помещает IOLoop в несчастливое состояние для будущих взаимодействий.Закрыть и сбросить Tornado IOLoop после KeyboardInterrupt

In [1]: from tornado import gen 
In [2]: from tornado.ioloop import IOLoop 
In [3]: IOLoop.current().run_sync(lambda: gen.sleep(100000)) 
KeyboardInterrupt: 

In [4]: IOLoop.current().run_sync(lambda: gen.sleep(1)) 
RuntimeError: IOLoop is already running 

Какие операции я должен делать между [3] и [4], чтобы очистить или заменить застрял IOLoop. Некоторая комбинация .stop, .close, .close_current и .close_instance работала для меня в прошлом.

ответ

1

После KeyboardInterruptIOLoop оставлен в неопределенном состоянии и не может быть безопасно перезапущен. (Это справедливо для большинства объектов: редка для объекта по-прежнему может быть использована после того, как метод был прерван, если только этот метод не был доступен только для чтения).

Если вы хотите восстановиться с C-c, вам придется написать свой собственный обработчик сигнала вместо использования по умолчанию, который вызывает KeyboardInterrupt. Например, чтобы просто остановить IOLoop и оставить его в возобновлении состояния, вы могли бы сделать что-то вроде этого (непроверенное):

def sigint_handler(sig, frame): 
    io_loop = IOLoop.current() 
    io_loop.add_callback_from_signal(io_loop.stop()) 
signal.signal(signal.SIGINT, sigint_handler) 

Если вы хотите поднять исключение после прерывания таким образом, вы будете должны внести изменения в код, который вызывает IOLoop.start.

+0

Чтобы быть ясным, я не хочу повторно активировать текущий IOLoop. Я был бы вполне доволен отказом от него и созданием нового. – MRocklin

+0

А, это намного проще. Вы можете попытаться вызвать 'close()' на старом, но будьте готовы к исключению. Вызов 'install()' (если предыдущим IOLoop был 'instance()') и 'make_current()' должно быть достаточно, чтобы заменить старый. Но это все еще может измениться в будущих версиях Tornado; единственным способом, который действительно гарантированно быть безопасным, является замена обработчика сигнала тем, что не вызывает 'KeyboardInterrupt'. –

Смежные вопросы