9 Replies Latest reply on Jan 4, 2014 2:27 AM by areohbee

    Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?

    Rik Littlefield

      Hi -- I need some help again!

       

      I'm writing an export plugin for my own application. 

       

      On Windows, everything works as expected -- I can start the export and then go back to doing other tasks in Lightroom while my application does its own thing.

       

      But on Macintosh, Lightroom hangs with the rotating "busy" icon until my application quits.

       

      I am baffled by this behavior because I think I've wrapped everything I'm doing in calls to LrTasks.startAsyncTask.

       

      Apparently I'm missing something about how asynchronous tasks work in Lightroom, or at least in Lightroom on Macintosh.

       

      Do you have any suggestions about how I can get the Mac version to keep Lightroom responsive while my exported-to application does its thing?

       

      Thanks!

       

      --Rik

       

      For further information...

       

      Mac OS X 10.9, Lightroom 4.2

       

      Here is the current structure of my ExportToMA.lua file

       

      local myLogger        = LrLogger("myLogger")

       

      myLogger:enable("logfile")

       

      ExportToMA = {}

       

      ExportToMA.outputToLog = function(param)

        myLogger:trace(param)

      end

       

      LrTasks.startAsyncTask( function()

          myLogger:trace("Entering outer LrTasks.startAsyncTask function")

          ...

          LrTasks.startAsyncTask( function()

              myLogger:trace("Entering inner LrTasks.startAsyncTask function")

              local activeCatalog = LrApplication.activeCatalog()

              local frameSet     = activeCatalog.targetPhotos

              local exportSession = LrExportSession( {

                  exportSettings = {

                      LR_exportServiceProvider       = "net.mydomain.MAloader",

                      LR_exportServiceProviderTitle  = "My Application",

                      LR_format                      = "TIFF",

                      LR_tiff_compressionMethod      = "compressionMethod_None",

                      LR_export_bitDepth             = 16,

                      LR_export_colorSpace           = "sRGB",

                      LR_minimizeEmbeddedMetadata    = false

                      },

                  photosToExport = frameSet,

                  } )

              myLogger:trace("Before doExportOnCurrentTask()")

              exportSession:doExportOnCurrentTask()       

              myLogger:trace("After doExportOnCurrentTask()")

              myLogger:trace("Exiting inner LrTasks.startAsyncTask function")

          end )

          myLogger:trace("Exiting outer LrTasks.startAsyncTask function")

      end )

       

      When run on Windows, the log file contains a sequence of messages like this:

       

      12/30/2013 10:36:48 TRACE    Entering outer LrTasks.startAsyncTask function
      12/30/2013 10:36:48 TRACE    Exiting outer LrTasks.startAsyncTask function
      12/30/2013 10:36:48 TRACE    Entering inner LrTasks.startAsyncTask function
      12/30/2013 10:36:48 TRACE    Before doExportOnCurrentTask()
      12/30/2013 10:36:49 TRACE    After doExportOnCurrentTask()
      12/30/2013 10:36:49 TRACE    Exiting inner LrTasks.startAsyncTask function
         <meanwhile my application continues to run while Lightroom stays responsive>

       

      But when run on Macintosh, this is what happens:

       

      2013-12-30 19:01:50 +0000, TRACE    Entering outer LrTasks.startAsyncTask function
      2013-12-30 19:01:50 +0000, TRACE    Exiting outer LrTasks.startAsyncTask function
      2013-12-30 19:01:50 +0000, TRACE    Entering inner LrTasks.startAsyncTask function
      2013-12-30 19:01:50 +0000, TRACE    Before doExportOnCurrentTask()
        <indefinitely long pause while my application runs>
      2013-12-30 19:02:44 +0000, TRACE    After doExportOnCurrentTask()
      2013-12-30 19:02:44 +0000, TRACE    Exiting inner LrTasks.startAsyncTask function

       

      Ideas?

        • 1. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
          areohbee Level 5

          Well, the async task is working, but the export-on-current-task seems strange. I mean, the Windows version should take longer (1 second for a multi-photo export - really?), and the Mac version shouldn't cause spinning beach ball. So, I'm guessing you have a bug in your export settings which just happens to manifest differently on different platforms - could that be? (for example, no export destination has been specified).

           

          Here's something you can try:

           

          instead of

           

          exportSession:doExportOnCurrentTask()

           

          do this:

           

          for i, rendition in exportSession:renditions() do

               local status, pathOrMessage = rendition:waitForRender()

               if status then

                    outputToLog( "Exported to "..pathOrMessage )

              else

                  outputToLog( "Unable to export - "..pathOrMessage )

              end

          end

          • 2. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
            Rik Littlefield Level 1

            > 1 second for a multi-photo export - really?

             

            Sorry, I forgot to mention that this was a tiny test and I ran it several times so everything would have been cached by the time the above log entries were captured.

             

            All the files that were supposed to get exported did get copied out and picked up as intended.

             

            > do this:
            > for i, rendition in exportSession:renditions() do ...

             

            There's already code like that in my processRenderedPhotos function that gets called by the doExportOnCurrentTask().

             

            The log did contain the expected messages indicating correct export, and my application picked up the images correctly from the temp directory where they had been written.

             

            > the export-on-current-task seems strange

             

            Other than the spinning beach ball, everything appears to be working fine.  But I'm still stuck with the spinning beach ball and it's driving me nuts.

             

            Any other ideas?

             

            --Rik

            • 3. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
              areohbee Level 5

              did you try doExportOnNewTask? (I don't think it will help, but maybe worth trying..).

               

              Do you have this problem with hard drive export too, or only the export service you are developing?

               

              PS - I'm confused by your application: if you already have a renditions loop, then why are you starting another export - I assume to export another copy, in which case you should NOT be specifying the same export service provider, should you?, or what am I missing - as I said I'm confused..

               

              Rob

              • 4. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
                Rik Littlefield Level 1

                > I'm confused by your application: if you already have a renditions loop, then why are you starting another export

                 

                I apologize for the confusion. 

                 

                In each case I've exercised, there is only one export and one renditions loop. 

                 

                The code I've been showing you is what gets executed to service a menu entry in File > Plug-In Extras.  I'm focusing attention on that case because it seems more transparent.  Notably, I get to specify which task the export happens on. 

                 

                The renditions loop in my processRenderedPhotos function is in another script.  The renditions loop gets called in two places: 1) from File > Plug-In Extras via the explicit doExportOnCurrentTask (now doExportOnNewTask), and 2) from Lightroom's internal processing of File > Export... and File > Export with Preset.

                 

                > did you try doExportOnNewTask?

                 

                I tried it just now.  It did not change the behavior.

                 

                I also added some more diagnostics.  Here is what happens on the Mac:


                2013-12-31 01:09:31 +0000, TRACE    Entering outer LrTasks.startAsyncTask function
                2013-12-31 01:09:31 +0000, TRACE    Exiting outer LrTasks.startAsyncTask function
                2013-12-31 01:09:31 +0000, TRACE    Entering inner LrTasks.startAsyncTask function
                2013-12-31 01:09:31 +0000, TRACE    Before doExportOnNewTask()
                2013-12-31 01:09:31 +0000, TRACE    After doExportOnNewTask()
                2013-12-31 01:09:31 +0000, TRACE    Exiting inner LrTasks.startAsyncTask function
                2013-12-31 01:09:31 +0000, TRACE    MyApplicationUploadTask.processRenderedPhotos prefs.maPath: /Users/myaccount/Desktop/MyApplication.app/Contents/MacOS/JavaApplicationStub
                2013-12-31 01:09:31 +0000, TRACE    tempPath: /var/folders/4n/2lxf6v593x5_c3lmx_jghgnw0000gn/T/temp_lre_ma_1230170931
                2013-12-31 01:09:31 +0000, TRACE    nPhotos = 2
                2013-12-31 01:09:32 +0000, TRACE    source path/Users/myaccount/Desktop/jpeg-8d/testorig.jpg
                2013-12-31 01:09:32 +0000, TRACE    destination path: /var/folders/4n/2lxf6v593x5_c3lmx_jghgnw0000gn/T/6F05FC8E-126C-47E0-AD51-C545CE0DA66D/tes torig.tif
                2013-12-31 01:09:32 +0000, TRACE    source path/Users/myaccount/Desktop/jpeg-8d/testprog.jpg
                2013-12-31 01:09:32 +0000, TRACE    destination path: /var/folders/4n/2lxf6v593x5_c3lmx_jghgnw0000gn/T/6F05FC8E-126C-47E0-AD51-C545CE0DA66D/tes tprog.tif
                2013-12-31 01:09:32 +0000, TRACE    just before LrShell.openFilesInApp

                 

                   <long pause here, while I let my application run for a while>

                 

                2013-12-31 01:10:00 +0000, TRACE    just after LrShell.openFilesInApp

                 

                The LrShell.openFilesInApp call happens after my renditions loop, at the very bottom of my processRenderedPhotos function, which is now separated by 3 levels of asynchronous tasks from whatever task initially serviced the menu entry.

                 

                Nonetheless, on Macintosh only, as soon as LrShell.openFilesInApp is called, Lightroom comes to a grinding halt heralded by a spinning beach ball. 

                 

                It's as if, deep under the covers, LrShell.openFilesInApp (on Macintosh only!) is telling the rest of Lightroom to wait until the spawned application terminates. 

                 

                I know, it sounds crazy to me too, and I've been programming for close to 45 years.

                 

                At the moment, the only way I see to work around this problem is to provide a separate "application" that is actually a spawn-and-terminate, so that LrShell.openFilesInApp will see a rapid termination of the thing that it launches.  That seems like a lot of trouble for what I've been hoping is a simple misunderstanding on my part.

                 

                The one thing I can see different between my app and anybody else's is that mine is written in Java, so the thing that gets launched by LrShell.openFilesInApp is the JavaApplicationStub.

                 

                Any other ideas?

                 

                --Rik

                 

                PS.

                > Do you have this problem with hard drive export too?

                I doubt it, but I don't know for sure.  On my test Mac, at the moment, there are not enough files to keep hard drive export running long enough to notice.

                • 5. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
                  areohbee Level 5

                  Thanks Rik,

                   

                  Unfortunately, I don't know why you're having this problem (spinning beach ball).

                   

                  I mean, I've seen it a lot whilst developing plugins, and the reason, in general, has always been clear:

                   

                  Lightroom (or the plugin) is hogging the CPU and not giving it up for the rest of the stuff to do what it does.

                   

                  So, in general, the solution is to add LrTasks.yield() in the various loops of the plugin.

                   

                  However, if you have rendition:waitForRender() that should be yielding.

                   

                  Anyway, if you've been programming for 45 years then you no-doubt have the expertise to trouble-shoot.

                   

                  PS - regarding openFilesInApp, you can try LrTasks.execute instead. I mean, it will also block the task, so you may still need an async task. Reminder: on Mac, you may want to try executing the open command instead of executing the app itself.

                   

                  Good luck,

                  Rob

                  1 person found this helpful
                  • 6. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
                    Rik Littlefield Level 1

                    > Anyway, if you've been programming for 45 years then you no-doubt have the expertise to trouble-shoot.

                     

                    Alas, only a few days of that time has been inside Lightroom and Lua.  So while I have lots of experience in general, I'm definitely a newbie in this environment

                     

                    > PS - regarding openFilesInApp, you can try LrTasks.execute instead.

                     

                    Bingo!  It turns out that on Mac, LrTasks.execute seems to be just what I need.  On Windows, LrTasks.execute is broken for my purposes, because it doesn't seem to tolerate quoted arguments to the application being invoked.  But that's OK, I can test for Windows versus Mac and do LrTasks.execute on the Mac and LrShell.openFilesInApp on Windows.  At the moment (in very brief testing), my plugin now seems to be exhibiting user-friendly behavior on both platforms.

                     

                    I greatly appreciate your assistance -- many thanks!

                     

                    --Rik

                    • 7. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
                      areohbee Level 5

                      Hi Rik,

                       

                      I'm glad you're making progress...

                       

                      Rik Littlefield wrote:

                       

                      On Windows, LrTasks.execute is broken for my purposes, because it doesn't seem to tolerate quoted arguments to the application being invoked.

                      You just need to wrap the whole command line in double-quotes, on Windows.

                       

                      ~R.

                      • 8. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
                        Rik Littlefield Level 1

                        Rob,

                         

                        Things are looking very good.

                        Rob Cole wrote:

                         

                        Rik Littlefield wrote:

                         

                        On Windows, LrTasks.execute is broken for my purposes, because it doesn't seem to tolerate quoted arguments to the application being invoked.

                        You just need to wrap the whole command line in double-quotes, on Windows.

                        I'll have to take your word for that.  I couldn't make it work. 

                         

                        The command lines I used for testing looked like this:

                         

                          "C:\Program Files\MyApp\myapp.exe" -lrplugin SecondArgument

                          "C:\Program Files\MyApp\myapp.exe" -lrplugin "SecondArgument"

                          "C:\Program Files\MyApp\myapp.exe" -lrplugin "Second Argument"

                         

                        If I copy/pasted any of these lines into a Command Prompt window, then my app worked fine.  The first form also worked fine if I passed it to LrTasks.execute.  But as soon as I added the double quotes around the second argument, LrTasks.execute stopped working.  I tried it with no added double-quotes around the whole line, with added double-quotes at beginning and end, and even with just an added double-quote at the beginning.  All failed in various ways.  I gave up at that point because LrShell.openFilesInApp was working fine for me, so investigating LrTasks.execute on Windows was just for curiosity.

                         

                        Rob Cole wrote:

                         

                        Reminder: on Mac, you may want to try executing the open command instead of executing the app itself.

                        That's another good hint, although I'm not sure that I'm doing exactly what you intended.  Anyway, using the Mac's "open" command to execute my app provides the launch-and-terminate functionality that I considered writing for myself.  On the Mac, using LrTasks.execute to run "open" to launch my application both 1) allows Lightroom to remain responsive while the export happens, and 2) allows the user to cleanly terminate Lightroom if they want to, while leaving my application running on copies it made of Lightroom's exported files.

                         

                        Everything is now working fine for purposes of this thread.

                         

                        Many thanks for your help!

                         

                        --Rik

                        • 9. Re: Export plugin on Macintosh not honoring LrTasks.startAsyncTask ?
                          areohbee Level 5

                          Yep, wrap the whole command line in double-quotes - that's the secret on Windows.

                          Yep, using 'open' to execute your app on Mac is exactly what I was suggesting.

                          Glad you got it working .

                          R