Copy link to clipboard
Copied
From what I can tell, whenever I re-load a plugin, it (*mostly*) cleans up after the old one, then reloads...
This is fine, except one item it does not clean up is any asynchronous tasks started by the plugin. And, since the new load has a different variable context, its hard to detect and stop a previously started task.
Or something like this.
Any light that could be shed would help make it clearer whats going on when a plugin re-loads/initializes. And, if my above statement is fairly accurate, then consider this a feature request to add Tasks to the list of things to cleanup when a plugin is re-loaded.
Rob
[Oops, hit send too soon.]
Or use LrShutdownPlugin? The LrShutdownPlugin would set a global variable "stopAsyncTasks" to true, and the background task polls that variable.
Copy link to clipboard
Copied
Or maybe expire the task after x minutes of inactivity?
Copy link to clipboard
Copied
Unfortunately, they are still very much active, and therein lies the problem. - I can't see a way for them to realize they should become inactive. I think it needs to be detectable somehow that the context in which they were started has been unloaded. I haven't yet figured out a way to detect that.
Copy link to clipboard
Copied
A hack workaround: When the persistent background task first starts, it writes the current time into a temp file and remembers that time. It reads the contents of the file every n seconds, and if it changes, it exits.
Copy link to clipboard
Copied
A different solution: In the plugin's global environment, define a global variable "sentinel" whose value is a dummy table:
sentinel = {value = "dummy table"}
In the background task, create a Lua weak table that references the value of "sentinel". The background task periodically checks the value of the weak reference, and if it is nil, then you know the that the dummy table has been garbage collected, indicating that the global environment of the plugin has gonne away, indicating the plugin has been reloaded.
A potential problem with this solution: You don't know when the garbage collector will actually run. It may be that in practice, it runs very frequently, but I don't know that.
Copy link to clipboard
Copied
Or use LrShutdownPlugin?
Copy link to clipboard
Copied
[Oops, hit send too soon.]
Or use LrShutdownPlugin? The LrShutdownPlugin would set a global variable "stopAsyncTasks" to true, and the background task polls that variable.
Copy link to clipboard
Copied
Thank you John for all your helpful suggestions. I will try in a while and report back.
Please standby...
Rob
Copy link to clipboard
Copied
johnrellis wrote:
The LrShutdownPlugin would set a global variable "stopAsyncTasks" to true, and the background task polls that variable.
Yep - it was really that easy: problem solved.
Thanks John,
Rob.
Copy link to clipboard
Copied
Ellis,
where exactly do you recommend to use LrShutdownPlugin.. there is no callback that check for unloadPlugin... or is there?
Copy link to clipboard
Copied
abazizis,
The documentation is misleading, but if you specify a lua filename string for LrShutdownPlugin, it will get executed before LrInitPlugin when the plugin is re-loaded (but not when its loaded for the first time).
I don't know about any other occasions where it might be called, but its perfect for stopping tasks...
Rob
Copy link to clipboard
Copied
FYI - Some important notes about LrInitPlugin and LrShutdownPlugin:
The global environment is shared with the rest of the plugin, but the local environment is not.
In other words, if you initialize local variables in a module via LrInitPlugin, the initialization will not be seen by the service provider or export provider, since it executes in a different local environment.
Put another way - if you want to initialize variables used by a service provider or export module via lr-init-plugin, then you'd better put the intialized variables in the global "namespace" - _G.
Rob
Copy link to clipboard
Copied
One more thing:
If you want lr-plugin-init to be called when lightroom first starts, you have to have a custom metadata item (if you dont want one - declare a dummy hidden one).
That's it for now...
Copy link to clipboard
Copied
If you want lr-plugin-init to be called when lightroom first starts, you have to have a custom metadata item (if you dont want one - declare a dummy hidden one).
Excellent discovery, thanks.
Copy link to clipboard
Copied
johnrellis wrote:
...Excellent discovery, thanks.
That tidbit represents about 5 hours worth of work for me. - if you're smarter/luckier... than me, it may save you less - if you're dumber/un-luckier..., could save you days, or even weeks...
You're welcome - that's all I'm sayin'...
Rob
Copy link to clipboard
Copied
And now the "final" answer to the question: "When, exactly, is LrInitPlugin called?"
- If you have custom metadata defined, then its called when Lightroom starts up, otherwise its called when you first select the plugin in the manager (and if it was already selected in the manager, then its called when you first open the manager). If you don't open the manager, then its called upon first use. Also called when you click the 'Reload Plugin' button - or if 're-load plugin on each export' is checked, its called everytime before invocation - whether its via an export or menu selection.
Did I get that right?, or miss anything??
Rob
Copy link to clipboard
Copied
Thanks Rob for your effort... glad you with us..
Copy link to clipboard
Copied
abazizis,
Thanks bud - its good to be appreciated, especially in this sometimes harsh and seemingly unappreciative forum.
PS - Glad you're with us too, and you're welcome...
Rob
Copy link to clipboard
Copied
To be clearer (maybe) - LrShutdownPlugin - global namespace is same as loaded plugin.
But, once the plugin has been re-loaded, even _G is fresh.
Thus, LrShutdownPlugin shares the same _G as the previous invocation of LrInitPlugin and such, but LrInitPlugin and the rest will have a brand-spanking new _G than the last call to LrShutdownPlugin did, when the plugin is reloaded.
Makes sense?
Rob