Closed deathaxe closed 5 years ago
I'm assuming BracketHighlighter suffers from this as well. Essentially, there is a thread that is employed that is used to reduce how often plugin busy work occurs. For instance, when someone is typing, we don't want to run our payload on every keypress. So what we do, when one of these key or selection or various other events take place, is wait for events to stop coming in before executing the payload. So if you start typing, the plugin realizes it needs to update things, but waits for the typing to die down for X about of time before updating.
So yes, currently that thread is running in the background. It's possible we can kill it after so much idle time and restart it on certain events. It will require quite a bit of testing to make sure we get it right. When I get some time, I can look into it. I don't know when that will be.
I haven't evaluated how ColorHelper employs this yet, I'm mainly speaking from a BracketHighlighter perspective, my most used plugin. I think ColorHelper looks out for scrolling to decide when it updated color. It may be more difficult to do that without having a constant running thread as their are no real events to trigger that.
In short, I'll have to evaluate each plugin that used similar logic and address them base on how they do things. I imagine HexViewer can be solved much the same way as BracketHighlighter. But we'll have to see. This is probably low priority for me, but a valid issue that probably should be addressed where possible.
Thanks for looking into.
It's possible we can kill it after so much idle time
Would just need to set the thread to sleep if not needed, instead?
I wrote a little helper plugin for my job which uses a permanent background thread with a Queue to pull expensive tasks to as I wanted to avoid creating tons of threads again and again.
See: https://github.com/deathaxe/sublime-scp/blob/master/core/task.py
It keeps completely quite, if ST is idle.
Just trying to apply that strategy to GitGutter as well.
there is a thread that is employed that is used to reduce how often plugin busy work occurs.
GitGutter does so as well, but with the use of ST's set_timeout_async()
.
A bit more sophisticated version of that debouncing can be found in the same file. It ensures to have only one timer active at a time.
Cool. We don't spawn multiple threads simultaneously, nor would I want to. Causing the thread to sleep may be exactly what we are looking for. I'll take a look at some of your suggestions when I dig deeper into this.
I think I have a workable solution that I will work on getting implemented across all the plugins that employ threads in a similar way. I see now that the the key is simply: self.queue.get()
as that seems to put the thread to sleep as the thread goes idle waiting for the task. In our case, we don't really need multiple tasks, but on an event we can create a task where we start looking at events, and when enough time has gone by without an event, we can execute the payload and clear the task putting us back to sleep.
I've done this experiment with BracketHighlighter and was able to get CPU usage to 0% during idle time, so this will translate over to ColorHelper, HexViewer, etc. with no issues.
While I can ensure threads generally go idle, there is one that I cannot. Particularly the one that checks for when a user is scrolling. But I will at least work to ensure anything else is idle.
Description
ColorHelper (and same for HexViewer) causes continues activity of both sublime_text.exe and plugin_host.exe even without any file being open and no activity taking place in the file (editing, moving curser, etc.).
Looks like some kind of polling takes place in the background. Even though the CPU usage is quite small, I'd rather expect both ColorHelper and HexViewer to keep quite if Sublime Text is completely idle.
plugin_host with ColorHelper enabled
plugin_host with ColorHelper disabled
Support Info
Steps to Reproduce Issue