You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Promise domains are broken when using certain coro operations (but not all of them). This means some operations using Shiny + elmer lose track about what Shiny session they belong to. tidyverse/ellmer#163
Primer on promise domains
With async programming, withr-style temporary state management won't work:
We want the effects of something like with_envvar to carry through the promise chain, until all the handlers that were bound within with_envvar are completed.
But it's not enough to simply extend the effect of with_envvar until the entire operation has completed--that is, set the env var when with_envvar() is called and delay unsetting the env var until the promise chain is completed. You can imagine two overlapping async operations that each want to set a different value for $FOO; whichever one started second would stomp on the value of the first.
Instead, we need a way to put each of the handlers in the promise chain in its own little with_envvvar. This is what promise domains let you do.
The way promise domains work is by installing themselves into the dynamic scope exactly like a normal withr function, but the effect it has is to intercept calls to promises::then (as well as functions and operators built on top like catch, finally, %...>%, etc.). They are also viral/recursive in that, whenever one of its intercepted then calls' callbacks are invoked, they install themselves as the current promise domain so that the callbacks' then calls are also intercepted.
(The original design doc is in this gist, but the examples above are better. Also the original design doc didn't have wrapSync, which is used to wrap the expression that's directly inside with_promise_domain()--without this, whatever side effect the promise domain was intended to perform/unperform would only happen in the promise callbacks, not in the synchronous code that launches the async operation in the first place.)
Simple reprex
The text was updated successfully, but these errors were encountered:
DRAFT
Promise domains are broken when using certain
coro
operations (but not all of them). This means some operations using Shiny + elmer lose track about what Shiny session they belong to. tidyverse/ellmer#163Primer on promise domains
With async programming,
withr
-style temporary state management won't work:We want the effects of something like
with_envvar
to carry through the promise chain, until all the handlers that were bound withinwith_envvar
are completed.But it's not enough to simply extend the effect of
with_envvar
until the entire operation has completed--that is, set the env var whenwith_envvar()
is called and delay unsetting the env var until the promise chain is completed. You can imagine two overlapping async operations that each want to set a different value for$FOO
; whichever one started second would stomp on the value of the first.Instead, we need a way to put each of the handlers in the promise chain in its own little
with_envvvar
. This is what promise domains let you do.The way promise domains work is by installing themselves into the dynamic scope exactly like a normal withr function, but the effect it has is to intercept calls to
promises::then
(as well as functions and operators built on top likecatch
,finally
,%...>%
, etc.). They are also viral/recursive in that, whenever one of its interceptedthen
calls' callbacks are invoked, they install themselves as the current promise domain so that the callbacks'then
calls are also intercepted.(The original design doc is in this gist, but the examples above are better. Also the original design doc didn't have
wrapSync
, which is used to wrap the expression that's directly insidewith_promise_domain()
--without this, whatever side effect the promise domain was intended to perform/unperform would only happen in the promise callbacks, not in the synchronous code that launches the async operation in the first place.)Simple reprex
The text was updated successfully, but these errors were encountered: