##// END OF EJS Templates
confirm notebook shutdown on SIGINT...
MinRK -
Show More
@@ -20,6 +20,7 b' Authors:'
20 import errno
20 import errno
21 import logging
21 import logging
22 import os
22 import os
23 import select
23 import signal
24 import signal
24 import socket
25 import socket
25 import sys
26 import sys
@@ -450,10 +451,48 b' class NotebookApp(BaseIPythonApplication):'
450 break
451 break
451
452
452 def init_signal(self):
453 def init_signal(self):
453 signal.signal(signal.SIGINT, self._handle_signal)
454 signal.signal(signal.SIGINT, self._handle_sigint)
454 signal.signal(signal.SIGTERM, self._handle_signal)
455 signal.signal(signal.SIGTERM, self._signal_stop)
455
456
456 def _handle_signal(self, sig, frame):
457 def _handle_sigint(self, sig, frame):
458 """SIGINT handler spawns confirmation dialog"""
459 # register more forceful signal handler for ^C^C case
460 signal.signal(signal.SIGINT, self._signal_stop)
461 # request confirmation dialog in bg thread, to avoid
462 # blocking the App
463 thread = threading.Thread(target=self._confirm_exit)
464 thread.daemon = True
465 thread.start()
466
467 def _restore_sigint_handler(self):
468 """callback for restoring original SIGINT handler"""
469 signal.signal(signal.SIGINT, self._handle_sigint)
470
471 def _confirm_exit(self):
472 """confirm shutdown on ^C
473
474 A second ^C, or answering 'y' within 5s will cause shutdown,
475 otherwise original SIGINT handler will be restored.
476 """
477 sys.stdout.write("Shutdown Notebook Server (y/[n])? ")
478 sys.stdout.flush()
479 r,w,x = select.select([sys.stdin], [], [], 5)
480 if r:
481 line = sys.stdin.readline()
482 if line.lower().startswith('y'):
483 self.log.critical("Shutdown confirmed")
484 ioloop.IOLoop.instance().stop()
485 return
486 else:
487 print "No answer for 5s:",
488 print "resuming operation..."
489 # no answer, or answer is no:
490 # set it back to original SIGINT handler
491 # use IOLoop.add_callback because signal.signal must be called
492 # from main thread
493 ioloop.IOLoop.instance().add_callback(self._restore_sigint_handler)
494
495 def _signal_stop(self, sig, frame):
457 self.log.critical("received signal %s, stopping", sig)
496 self.log.critical("received signal %s, stopping", sig)
458 ioloop.IOLoop.instance().stop()
497 ioloop.IOLoop.instance().stop()
459
498
General Comments 0
You need to be logged in to leave comments. Login now