* Fix#2008: Allow eventReactive and observeEvent eventExprs to be async
This makes it possible to monitor e.g. async reactives.
In the process of fixing this, also discovered that observers don't
filter out shiny.silent.error (i.e. req(FALSE)) when they come back
from async operations. For example, this will kill the current
Shiny session instead of being ignored:
observe({
promise_resolve(TRUE) %...>%
{req(FALSE)}
})
This issue is also fixed in this commit.
* Enable deep stack trace by default, now that it's fast
We already had an `immediate` input option, which was used to override client side rate
limiting mechanisms (debounce/throttle). This commit extends the semantics of that option
to also mean that duplicate values should not be ignored on the client side.
Previous to this commit, circumventing the client side dedupe logic was not enough. The
server side ReactiveValues object was also subject to deduping. With this commit, the
low-level ReactiveValues class's constructor now has a `dedupe` option, which defaults
to TRUE; the ReactiveValues used for a session's input has it turned to FALSE. I figure
if I had to work this hard to get the client to stop sending duplicates, and the input
values are only expected to ever be updated by the client, then there's really no reason
for server side deduping to be performed for this particular ReactiveValues object.
It would make sense as a future feature to also make deduping optional for user-created
reactiveValues and reactiveVal objects.
- Moved (in|de)crementBusyCount calls out of Context and into Observer
- decrementBusyCount is (effectively) deferred for async observers until
the async operation is complete
- invalidateLater didn't force(session), almost certainly was buggy
- invalidateLater, reactiveTimer, and manageInputs all now use a new
session$cycleStartAction, which delays their effect until observers
(including async ones) are done executing
Also changed the classes of reactive expressions and reactiveVal
from "reactive" and "reactiveVal" to c("reactiveExpr", "reactive")
and c("reactiveVal", "reactive")
* added skipFirs arg to observeEvent
* create getCurrentObserver() function
* better NEWS entry
* made code more consistent
* implemented `once` param to `observeEvent`; extensive documentation for `getCurrentObserver`
* implement dig param to `getCurrentObserver`
* fix bug that was causing unit tests to fail
* take two
* git commit
* removed function getCurrentObserver
* delete .globals$currentObserver variable
* update docs
* typo
* remove dupes in index.r (bah humbug)
* rerun devtools::document
* Rename invalidateReactiveValue to freezeReactiveValue
* Make onFlush and onFlushed use 'once' argument
* session$flushOutput: schedule another flush if needed
* Catch all errors before they propagate to websocket
* Restore original logic for progressKeys
* Fix#931: Observer memory leak
Observers were being prevented from being garbage collected by
their own onReactiveDomainEnded() event handlers. This commit
fixes that by making sure that those event handlers are only
registered when autoDestroy=TRUE, and that they are unregistered
both on destruction and when autoDestroy is changed.
* Remove extraneous self$ prefixes
* Add comment explaining autoDestroyHandle
There are two problems I'm trying to solve here.
1) Somewhere along the way, exprToFunction gained a hardcoded
assumption that two stack frames up is a variable "expr",
meaning anything that called installExprFunction had to have
the first argument be exactly "expr". I think I got this
fixed, now the only assumption made by both installExprFunc
and exprToFunc is if they are called with quoted = FALSE,
then the caller is merely passing through code that originated
exactly one more level up the stack frame. If the code is
less than one level up, i.e. an end user is directly passing
code into installExprFunction or exprToFunction, then it won't
work; and if the code is more than one level up (someone is
passing code into function A which passes through to function
B which calls installExprFunction, with quoted = FALSE) then
it also won't work.
2) registerDebugHook calls were broken in various places by the
name/envir registered with the hook being different than the
name/envir through which the function was actually called.
This generally seems fixable by moving the registerDebugHook
call closer to the name/envir that will ultimately be called
(e.g. call registerDebugHook directly from wrapFunctionLabel).
There still seems to be a problem here in that breakpoints in
RStudio are hit but then the IDE automatically runs "n" multiple
times. Also the unit tests don't currently pass, I haven't
investigated that yet.