New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clean BG processes created by %%script on kernel exit #1981
Conversation
The standard library atexit module can call functions when the |
After I added
Need more time to debug... |
No, I don't need atexit for this behavior. |
I'm a bit puzzled by that. From what I can see, it should wait for non-daemon threads - but the only other thread we use is a daemon. And we use |
Ah, I see, backgroundjobs uses non-daemon threads. That's what's |
Re: backgroundjobs / daemon: which makes more sense? It seems to me like they should be daemon, because if you start a few tasks in the background and then exit, those tasks should complete before the process ends, unless the exit is forceful (i.e. by a signal). |
Note that the behaviour you describe (waiting for them to finish) would mean they're not daemon. Starting a background job with |
I didn't know about daemon property, but I guess using daemon threads mean that you need to do invoke any cleanup for these thread from the main thread, right? I think this is preferable for script magic, because we can use atexit. If the question @minrk asked is to terminate BG processes or not, I think they should be terminated. I was running some quick server in notebook and after restarting the notebook kernel I could not restart the server because the port was already in use. So I needed to grep through the output of ps and kill the process to execute the code in notebook again. |
If it's running in a terminal, it could perhaps prompt on shutdown: "2 |
But if you start a background process in bash, it lives forever. I would expect one of the following:
daemon threads does neither of these. |
A quick test suggests that if the thread running the subprocess is a |
I think the confirmation dialog is not worth the complication. Let's go with daemon threads and force kill, as @takluyver suggested. It's not what I would expect, but it is the least likely to have unpleasant surprises. |
In my zsh, @takluyver Yes, I think that's reasonable behavior. @minrk I guess you need multiprocessing for 1. I think 2 is the current status and probably a good default. But I think having terminate-on-exit option would be nice. What do you think? Or more in general,
|
I don't think we need an |
I don't think there's any need to do anything complicated. Let's just change scripts to use daemon=True, and register kill with atexit. I agree with @takluyver that %onexit provides no benefit beyond atexit.register. |
Ah, I missed the two messages before my post. If it's OK to kill forcefully, I will stick to that. And if daemon thread works that way, right, atexit is fine. |
I added atexit and it works almost fine. When I start ipython by
exiting ipython kills sleep. However, when I start ipython using kernel |
On what system can you reproduce #1984? I've tried everything I can think of, and it always works fine. |
I am using Ubuntu 11.10 (x86_64). |
I noticed that after restarting kernel, old kernel becomes defunct. After sometime it is no longer there (doesn't show up in ps) and then I can restart kernel. |
Use shutdown requests rather than hard kills in notebook
So this is working now? |
And does it fix #1984 as well? |
Yes, it fixes #1984. |
I just checked that cleanup works in qtconsole if #1988 is merged. |
Okay, then I think this should be ready to merge, right @takluyver? The terminal console is a bit weird - Even know I don't really understand how it shuts down. |
Right - the qtconsole was always better, because it did proper shutdown. That's where I got the fix from to use here. |
I tweaked %killbgscripts magic a bit because it was too silent (and the dummy argument was ugly). |
try: | ||
p.kill() | ||
except: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's assign self.bg_processes = []
at the end of this, so that the list doesn't keep growing forever.
Good point. Fixed. |
It looks OK to me, but has someone tested on Windows? I know there are some differences in process control. |
On Windows I do get the 'address in use' error, before and after this change when there is a running script subprocess (background or not). This is true for any running subprocess, regardless of the %%script magic. I expect this is true in 0.12 as well. If I recall, Windows is just slower at releasing ports, so restart_kernel might just want a sleep on Windows. |
Since the Windows bugs are not a regression, I think this can be merged as-is and Windows can be addressed at a later point (perhaps not for 0.13). I think the %%script magic will be significantly less popular on Windows, anyway. |
I will merge this, and retag 1984 as a Windows-specific bug, now that it's addressed on sensible platforms. |
Clean BG processes created by %%script on kernel exit * uses less forceful shutdown of kernels in the notebook, allowing atexit machinery to fire * enables daemon BackgroundJobs * cleanup %%script --bg subprocesses at shutdown
Thanks. |
Clean BG processes created by %%script on kernel exit * uses less forceful shutdown of kernels in the notebook, allowing atexit machinery to fire * enables daemon BackgroundJobs * cleanup %%script --bg subprocesses at shutdown
This patch does not work yet because
__del__
method is not guaranteed to be called on exit. Are there any hook in kernel which is called when the kernel exits?