Sublime Forum

[ST3 BUG]Inaccessible View properties in async event

#1

Hi, a question for ST3 gurus.

I try to use the new async event listener in various plugin and have some issues beginning with this one:
When async event is called, the underlying view could have been modified, which is perfectly understandable.
But in some case, it look like the view is in a closing state, where lot of it’s method isn’t available.

With this code:

[code]import sublime, sublime_plugin

class ExampleCommand(sublime_plugin.EventListener):
def on_load_async(self, view):
print(view.file_name())[/code]
If I open the Goto Anything (ctrl+p) panel and slowly navigate among unopened files, the filenames are printed in the console.
If I navigate quickly among unopened files, the filenames is replaced with a None in the console.

It’s probably because the view is already closed before the event is triggered.
My question is:
How I can detect that the view is in a closing state ?

Thanks for your help.

0 Likes

#2

Changed the topic’s title, I think it’s a bug, or at least a shortcoming that need a solution.
If an event is triggered with a view argument, the view must be fully accessible or there must be a way to check the state of the view.

0 Likes

#3

This isn’t a bug.

In an async event, Views can be closed at any time, which will render the view_id invalid. This causes all methods to return default values instead. You can test for this by seeing if buffer_id() returns 0, although I’ll add a more explicit function in the next build.

0 Likes

#4

Thanks for the answer.

I tried many things to find a way to detect a closed view, but I missed buffer_id().

I think also that a function in the View class with a explicit name will be very welcomed.
A note in the documentation (http://www.sublimetext.com/docs/3/porting_guide.html) could be useful too.

0 Likes

#5

Also, keep in mind that testing for buffer_id() (or later, is_valid()) intrinsically suffers from a race condition: it can return True, but the View can still be closed before the next statement of your plugin runs. Essentially, if is_valid() returns False, then the View is definitely invalid, but if it returns True, then it may or may not be valid by the time the plugin runs.

1 Like

#6

argh, I’ve just hit this case.
The on_load_async check buffer_id() before running a plugin method, but the buffer_id() change to 0 during the processing.

There’s something I don’t fully understand here:
Is this behavior limited to the async events ?
Does the non async events run in the main thread (or block other threads) ?
If I replace the on_load_async by a on_load, does the view could change before the on_load finish ?

0 Likes

#7

on_load blocks the whole application while it runs, so the view won’t be closed or otherwise modified underneath you.

If you’re only doing a small amount of processing, then on_load is fine (not to mention simpler), however if you’re doing a lot of processing, or any IO at all, then you’ll make things slow by doing it in on_load

0 Likes

#8

We have save problem, we doing long time running process in on_xxx_async() event with a with RLock: statement, and after the View closed, the thread who running the on_xxx_aync() event seems be killed without RLock be released. So other thread will be blocked forever. Could we have a event to be send a notification if a thread was killed?

0 Likes