Skip to content

Commit

Permalink
Address ("fix" is too strong a word) #1791, #2946: freeze/thaw
Browse files Browse the repository at this point in the history
1. freezeReactiveValue(input, "x") is called, inside a renderUI
   or in an observer that then calls updateXXXInput
2. Some reactive output tries to access input$x, this takes a
   reactive dependency but throws a (silent) error
3. When the flush cycle ends, it automatically thaws

What's *supposed* to happen next is the client receives the new
UI or updateXXXInput message, which causes input$x to change,
which causes the reactive output to invalidate and re-run, this
time without input$x being frozen.

This works, except when the renderUI or updateXXXInput just so
happens to set input$x to the same value it already is. In this
case, the client would detect the duplicate value and not send
it to the server. Therefore, the reactive output would not be
invalidated, and effectively be "stalled" until the next time it
is invalidated for some other reason.

With this change, freezeReactiveValue(input, "x") has a new side
effect, which is telling the client that the very next update to
input$x should not undergo duplicate checking.
  • Loading branch information
jcheng5 committed Sep 18, 2020
1 parent 5e74478 commit fae27bf
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 3 deletions.
11 changes: 11 additions & 0 deletions R/shiny.R
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,18 @@ ShinySession <- R6Class(

impl <- .subset2(x, 'impl')
key <- .subset2(x, 'ns')(name)

impl$freeze(key)
if (identical(impl, private$.input)) {
# Notify the client that this input was frozen. The client will ensure
# that the next time it sees a value for that input, even if the value
# has not changed from the last known value of that input, it will be
# sent to the server anyway.
private$sendMessage(frozen = list(
ids = list(key)
))
}

self$onFlushed(function() impl$thaw(key))
},

Expand Down
19 changes: 19 additions & 0 deletions inst/www/shared/shiny.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion inst/www/shared/shiny.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion inst/www/shared/shiny.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion inst/www/shared/shiny.min.js.map

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions srcjs/init_shiny.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ function initShiny() {
inputs.setInput(name, value, opts);
};

// By default, Shiny deduplicates input value changes; that is, if
// `setInputValue` is called with the same value as the input already
// has, the call is ignored (unless opts.priority = "event"). Calling
// `forgetLastInputValue` tells Shiny that the very next call to
// `setInputValue` for this input id shouldn't be ignored, even if it
// is a dupe of the existing value.
exports.forgetLastInputValue = function(name) {
inputsNoResend.forget(name);
};

var boundInputs = {};

function valueChangeCallback(binding, el, allowDeferred) {
Expand Down
3 changes: 3 additions & 0 deletions srcjs/input_rate.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ var InputNoResendDecorator = function(target, initialValues) {

this.lastSentValues = cacheValues;
};
this.forget = function(name) {
delete this.lastSentValues[name];
};
}).call(InputNoResendDecorator.prototype);


Expand Down
6 changes: 6 additions & 0 deletions srcjs/shinyapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,12 @@ var ShinyApp = function() {
});
});

addMessageHandler('frozen', function(message) {
for (let i = 0; i < message.ids.length; i++) {
exports.forgetLastInputValue(message.ids[i]);
}
});

function getTabset(id) {
var $tabset = $("#" + $escape(id));
if ($tabset.length === 0)
Expand Down

0 comments on commit fae27bf

Please sign in to comment.