Delay between shiny:busy and next shiny:idle, how to detect that inputs needing "recalculation" are still in the queue

shiny
performance

#1

Hi,

Context:

  • Shiny webapp with Shinydashboard tabs
  • Every tab has reactive "inputs"
  • We block (showing partly transparent div with info covering the whole window) when Shiny is busy by using below JS:
	$(document).on('shiny:busy', function(event) {            
      // show partly transparent div      
      $(".pro_cont").css("display", "block");      
      // remove timer so div remains if shiny is busy      
      if (timerR !== false){        
        clearTimeout(timerR);        
        timerR = false;        
      }
    	
    });
    
    // hide partly transparent div    
    $(document).on('shiny:idle', function(event) {      
      // timer removing partly transparent div      
      timerR = setTimeout(function(){            
        // hide partly transparent div        
        $(".pro_cont").css("display", "none");        
      }, 400);
    	
    });

Thanks to this, tab is "active" when content of the tab is fully loaded.

Problem:

  • There is a tab with more complex reactive structure e.g. one reactive group of inputs triggers another reactive inputs (without any action from user side, just one by another)

We noticed that under heavy load (run via RStudio, so very rare, but possible scenario), when the first group of reactive inputs are loaded, but the second group is supposed to be "recalculated", delay between shiny:idle and next shiny:busy > timer value (delay around 2-4 seconds). As a consequence, partly transparent div is hidden while the content is not fully generated (and it seems webapp is frozen, but not as same symptoms as when disconnected). From shiny.trace:

1534106229.38471  SEND {"recalculating":{"name":[...],"status":"recalculating"}}
1534106235.00981  SEND {"recalculating":{"name":[...],"status":"recalculated"}}
1534106235.02798  SEND {"busy":"idle"}
1534106235.09994  SEND {"errors":[],"values":[...]}

# 2 seconds delay

1534106237.31619  RECV {"method":"update","data":[...]}
1534106237.56872  SEND {"busy":"busy"}
1534106237.65148  SEND {"recalculating":{"name":[...],"status":"recalculating"}}
1534106238.71478  SEND {"recalculating":{"name":[...],"status":"recalculated"}}

Of course we could rise value of timer, but this would block unnecessary for longer tabs with the simpler content.

Question: how to detect this kind of case, so partly transparent div can remain until the whole content of tab is loaded? Is there a way to detect that something more in the queue(?) on client (via JS) side should be "recalculated"?