Open FichteFoll opened 4 years ago
Since Windows doesn't ship Python by default, we may be able to get the same result with a PowerShell script. I can't really help with that, however.
If it is not found installed, we could ship some Python :stuck_out_tongue: Python is good for your health :innocent:
The good news is that Sublime already comes with a perfectly serviceable Python interpreter: plugin_host
. The bad news is that a) this is the thing that we want to wait on, and it can't wait on itself, and b) it doesn't end via sys.exit()
so we can't use atexit
to register exit handlers.
What we can do, though, is:
1. Fork plugin_host
.
2a. In the parent, os.wait()
for the child.
2b. In the child:
1. Do normal daemonization stuff (close fds, chdir, whatever).
2. Fork.
3a. In the parent, os._exit(0)
.
3b. In the child:
1. Set an atexit
handler to:
1. Sleep in a loop until the original plugin_host
PID is gone.
2. Run cleanup code.
2. sys.exit(0)
.
Reusing plugin_host is a neat idea because it means packages don't need to provide executables (and a .no-sublime-package
), since we can run the cleanup code from within ST's environment. Unfortunately, again, this won't work on Windows.
Why do we need to os.wait()
though? couldn't we just use the first child already?
Unfortunately, again, this won't work on Windows.
Ugh. I forgot that Windows doesn't have fork
. Is there a similar strategy that might work for Windows? The important thing about fork
is that it allows you to continue execution in a Python interpreter that's already set up and ready to go, without worrying about how to initialize plugin_host
or about multiple hosts interfering with each other. (It occurs to me that a hypothetical version of Sublime supporting a new Python runtime might be better behaved in this regard.)
Why do we need to
os.wait()
though? couldn't we just use the first child already?
I'm cribbing from the standard double-fork daemonization strategy. The purpose of the double-fork has to do with setsid()
; I forget the details. Our implementation might vary.
Apparently this issue is also related: https://github.com/SublimeTextIssues/Core/issues/10 (duplicate to the above mentioned).
And though it is an old issue, it was added to their "next dev cycle" milestone recently!
Oh, sneaky. I didn't notice that. Thanks for the heads-up.
Since this has been added for the new environment in 4050+, I believe we don't need this anymore, though I haven't tested it yet.
Agree, I think the ability to do cleanups by on_exit
event handlers is enough. The idea of starting arbitrary scripts upon or after application exit feels like a hack. The dependency of external script interpreters even makes it awkward and error prone.
Plugins should be able to do cleanups upon application startup etc. in case ST crashed and therefore didn't call on_exit
.
This is something that ST just cannot do at the moment and thus leaves plugins mostly struggling to clean up their resources or whatever. Because it's something that can be reused easily and only needs a single guardian process, there should be a centralized solution and sublime_lib provides a good opportunity to do so.
In essence:
Optional: Log errors or failed calls in some log file, probably in the cache.
I suppose using standard pipes for communication and declaring ST as having closed when the pipe is broken works, too.
Related: https://github.com/SublimeTextIssues/Core/issues/2950