ENH: webagg: Handle ioloop shutdown correctly#6334
ENH: webagg: Handle ioloop shutdown correctly#6334tacaswell merged 1 commit intomatplotlib:masterfrom
Conversation
|
The AppVeyor error was caused by one of the builds failing to download Miniconda correctly. |
7fda282 to
0494051
Compare
|
wouldn't it be simpler to just set If we are going to install a signal handler we need to capture the current handler, call it as part of our handler and then clean up by restoring the previous handler. |
|
I'm not sure I understand your question. |
|
Can you just add I am somewhat surprised that tornado does not stop it's self on a keyboard interupt |
|
That's what I tried first, but it didn't work. As far as I can tell, this is what happens in that scenario:
Specifically, the problem is that the only correct way to stop the IOLoop is by having it run a callback that triggers its |
|
Correction, that linked code is in a |
|
I suppose we could hack around the problem like this: I can confirm that this works, ugly as it is. The key is that for the IOLoop to be restartable, it needs to exit in a state where both This seems like least intrusive change that gets the job done, and apparently it's documented behavior. I'll update the PR to use this now. |
41c5a33 to
387f6c1
Compare
|
Travis failure is unrelated. |
| import random | ||
| import sys | ||
| import socket | ||
| import signal |
There was a problem hiding this comment.
do we still need this import?
There was a problem hiding this comment.
Nope, removed.
|
That makes sense, but I worry that it is going to be very dependent on the internal bits of tornado. I suspect that server people do not understand why you would want to start/stop/restart the server in the same process.... Is it worth trying to get the attention of someone from the tornado project on this? attn @mdboom |
|
I agree that it's treading pretty close to unexpected usage. The docs for
Maybe @bdarnell could clear things up? |
|
After an exception has escaped from |
|
Fair enough. @perimosocordiae Can you do the signal handling with a context manager? Something like @contextmanager
def signal_int_grabber():
old_sig = signal.signal(signal.SIGINT,
lambda sig, frame: ioloop.add_callback_from_signal(on_shutdown))
try:
yield
finally:
signal.signal(signal.SIGINT, old_sig)
with sig_int_grabber():
ioloop.start() |
69c8bad to
cbaf3b4
Compare
|
Sure, pushed and squashed. The |
|
❤️ pep8 This other wise looks good to me 👍 . |
This change correctly cleans up after the ioloop is interrupted, allowing the user to call plt.show(), then resume control with a SIGINT, then call plt.show() again.
cbaf3b4 to
500e6fd
Compare
|
Curses, off by one! Fixed and squashed. |
|
@jenshnielsen Can you review and merge this? Given that you found those issues from the nbagg refactor I take it use use webagg? |
|
This looks good to me. The misunderstanding about SIGINT not actually stopping the server was mine originally, and in fairness I only cared about the whole process stopping and never really considered starting up another server. This looks good to me, but it wouldn't hurt to get @jenshnielsen's opinion as well. |
|
@perimosocordiae Thanks! |
This change correctly triggers the
ioloop.stop()method, allowing the user to callplt.show(), then resume control with a SIGINT, then callplt.show()again.Without this change, any attempt to call
plt.show()after killing the webagg server the first time would result in an error because the ioloop instance hadn't been properly stopped.The motivation for using a signal handler comes from this SO answer, which is the only solution I could find that worked as intended.