10 Replies Latest reply on Aug 20, 2011 4:31 PM by areohbee

    publishedPhoto:getPhoto() needs to be called from a task context?

    clvrmnky Level 4

      Does publishedPhoto:getPhoto() need to be called from a task context? It appears to bail out in an ugly manner if not.

       

      If so, this is really, really inconvenient.

        • 1. Re: publishedPhoto:getPhoto() needs to be called from a task context?
          areohbee Level 5

          Just initiate the main function(s) of your plugin in async tasks and it'll make all those kinds of functions happy.

           

          Hint: use flags and cleanup handlers or lr-recursion-guard to keep them from being initiated again before completion.

           

          I use LrFunctionContext.postAsyncTaskWithContext to initiate most main functions, since it offers not only asynchronous execution, but a context for error handling and cleanup which is nearly always a good thing.

           

          Code examples available at: https://www.assembla.com/spaces/lrdevplugin/

          (see System/App and System/Call modules).

          • 2. Re: publishedPhoto:getPhoto() needs to be called from a task context?
            clvrmnky Level 4

            I'm pretty much already doing this, because I'm doing stuff in a menu item. So the main menu item/dialog callback is in an LrFunctionContext.

             

            Something else is at play here. The coroutine stuff in the SDK is a mess.

            • 3. Re: publishedPhoto:getPhoto() needs to be called from a task context?
              areohbee Level 5

              clvrmnky wrote:

               

              I'm pretty much already doing this, because I'm doing stuff in a menu item. So the main menu item/dialog callback is in an LrFunctionContext.

               

              Something else is at play here. The coroutine stuff in the SDK is a mess.

               

              So, the problem was *not* the need for it to be executed in an async task, but was something else?

               

              How is the coroutine stuff a mess?

              • 4. Re: publishedPhoto:getPhoto() needs to be called from a task context?
                johnrellis Most Valuable Participant

                Can you give a more detailed description of "It appears to bail out in an ugly manner"?  Error messages? 

                 

                Try wrapping the call to :getPhoto() in LrTasks.pcall() and then showing any resulting error in a dialog box or logging it to a file.

                • 5. Re: publishedPhoto:getPhoto() needs to be called from a task context?
                  clvrmnky Level 4

                  areohbee wrote:

                   

                  clvrmnky wrote:

                   

                  I'm pretty much already doing this, because I'm doing stuff in a menu item. So the main menu item/dialog callback is in an LrFunctionContext.

                   

                  Something else is at play here. The coroutine stuff in the SDK is a mess.

                   

                  So, the problem was *not* the need for it to be executed in an async task, but was something else?

                   

                  How is the coroutine stuff a mess?

                  No, it needs to be in some sort of task context, at least when called via a button gesture from a modal dialog running in it's own async context.

                   

                  The coroutine stuff is a twisty maze of passages. Most everything interesting has to be wrapped in layers ugly async or sync contexts, with all the attendant scope and locals thrashing that this suggests. At least, this is the case when inserting a chunk of code into a menu item so your plugin can do something reasonable contextual. All the example code I see out there seems to have the same pattern.

                   

                  It makes for boring, boilerplate code.

                   

                  I gave up on the elegant solution I wanted to have using the current selection and just went for a cheap/cheerful solution, so I no longer have the error message handy.

                  • 6. Re: publishedPhoto:getPhoto() needs to be called from a task context?
                    areohbee Level 5

                    I think I see what you mean, somewhat.

                     

                    You can't just write a button handler, (lest you risk having errors that aren't caught...), you have to wrap it in a task with a context, and associate an error handler with it...

                     

                    It took me a long time to come to that realization. I now have boring boilerplate code that I always use for wrappage so I forget about the old days...

                     

                    Would you, or how would you suggest Adobe improve this "mess"?

                     

                    Me? - dunno, maybe build that boilerplate stuff into Lr?, i.e. Lr traps any errors not caught by the handler so at least an error message can be displayed. And should they always be asynchronous? If so, should recursion always be guarded against? Maybe so - and if one wanted to be able to fire multiple concurrent tasks they still could by creating their own tasks that aren't guarded. Would there ever be a need for it *not* to be asynchronous?

                     

                    Haven't given this too much thought...

                     

                    But, I did just check - there is significant overhead in calling a function with a context vs. plain (without creating and destroying a context). So, it may be wise to wrap loops instead of wrapping functions called in a loop.

                     

                    Sometimes I think if Adobe was just clearer in the documentation, it would be an improvement, i.e. if it said in the api doc for button action functions that errors would be deep sixed, and functions requiring async tasks would fail, and provide an example of how to trap errors in an action handler...

                     

                    R

                    • 7. Re: publishedPhoto:getPhoto() needs to be called from a task context?
                      clvrmnky Level 4

                      Mostly just looking to make sure that getPhoto() needs to be called from a task context. This isn't necessarily an extreme problem, but it complicates some stuff enough that it becomes less ideal for me.

                       

                      But, it should be documented. It turns out that most publishedPhoto methods, even the getters, require a task gate in order to work. I'm not sure why this should be so, but we are talking about DB access here, so I suppose it seems reasonable.

                       

                      This is the general problem with all SDKs: they often force you to write a lot of boring code in order to not quite get what you want done. Something as simple as getting a selection and operating on it in a published context turns out to be such a gigantic mess of slow and brittle code that it is easy to see why so few plugins (even those from Adobe) offer much in the way of user interaction.

                       

                      I don't know how Friedl does it! I have literally hours a week available for this little project, so I just have to push on and muddle through it. I don't have time to replace entire frameworks at this point, and the varied ways that people have come up with clever solutions mostly add to my confusion. I admit this last issue is my own problem.

                      • 8. Re: publishedPhoto:getPhoto() needs to be called from a task context?
                        areohbee Level 5

                        In Aperture, one programs plugins in objective 'C' - i.e. there is no sandbox, per se. There *is* however limited access to Aperture - only what is provided in the .h file... But, plugins have all the computer as their world for everything else.

                         

                        Perhaps Adobe should have done the same thing (or still should do it) - programmer's choice for everything, except Lightroom access is constrained to the exposed API. Maybe just a Lua binding to the API, and users could call into Lua from their language of choice, which may be Lua, or Python, or Java, or .NET, or Objective 'C', or applescript...

                         

                        Dunno if this would make your particular problem better or worse, but at least one would not have to confine themselves UI-wise and other-wise..., and one would not have to learn a new language to program plugins.

                         

                        On the other hand, in general, I like the simple scripting approach, and I like Lua, so maybe just some robustening and polish...(?)

                         

                        PS - It is amazing to me some of the things Jeffrey Friedl has accomplished lr-plugin-wise... - still haven't figured out how he implemented the slick scrolling interface.

                         

                        Cheers,

                        Rob

                        • 9. Re: publishedPhoto:getPhoto() needs to be called from a task context?
                          clvrmnky Level 4

                          I like the script approach, as much of what we do is simply inserting something into an event loop.

                           

                          I'm just finding the event model and coroutine contortions a little tricky.  Part of this, I admit, is that I'm still figuring things out. But it doesn't help that the examples in the SDK docs cannot, generally, be built upon, and they also do not illustrate some of the trickier aspects of task management.

                           

                          For example, many of their dialogue examples use LrFunctionContext.callWithContext(), which will generally not work when adding things to the various menus uses. And the task stuff itself does not really match up with any event/atomic action/synchronized model I am familiar with.

                           

                          And, yes. I found an example of Friedl's code in a web search, which was sort of like finding a Rosetta stone of task management code.

                           

                          However, I pushed on and figured out most of what I needed to do, but the operation was pure unadulterated hacking with debug turned up to 11 until I found the right combination of async tasking until I was able to iterate through things in a reasonably robust manner. I'm pretty sure there are some bugs in there, but my examples were so crufty, and my need to push on so great, that I hesitate to make any statements beyond "wow, what a series of chores."

                          • 10. Re: publishedPhoto:getPhoto() needs to be called from a task context?
                            areohbee Level 5

                            Yeah, documentation/examples improvement would help even if same basic architecture maintained.