Replies: 1 comment
|
One interaction to settle before BristolMyersSquibb/blockr.core#317 and BristolMyersSquibb/blockr.dock#438 meet: dock's Called for each block before its server starts, the method runs for every block core constructs: at startup, and then through the background pass or, under this proposal, the Should opening the panel for a new block move out of |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Problem
Visibility is a front-end concern, but it sits in core, and demand is split around it:
board_server()function owns therequired,visibleandfrozenchannels, renders a block only oncevisiblereports it painted, and holds dock's build ledger in theNA/FALSE/TRUEstates ofvisible(Lift block UI build timing into the front-end API blockr.core#349, Let the front-end declare which blocks board_ui paints blockr.core#350).requiredchannel and theevaluate,sustainandconstructpayloads (Evaluation demand should be one multi-owner set, not two channels blockr.core#321). Whether a board gates must be known before the first flush, which no payload is.required_fulfilled()), then builds whatever is left.Once solved:
Proposal
sustainclaim set of Fold front-end demand into the one multi-owner claim set blockr.core#337, with the front-end one owner among several. The front-end declares itself when its callback is registered, together with its opening claim, and core seeds that claim under the callback's owner label before the first flush; a board without such a callback is not gated. The declaration sits with the callback, not the board class, because which callbacks a board was given decides who drives demand. That replaces the synchronousvisibility$gate()write and thegate_claimedlatch.visibility: hidden, which is how dockview hides back tabs.constructcomponent queues its ids in the order given, and core builds them one per idle tick after what evaluation needs, replacing the background pass andrequired_fulfilled(). A front-end sends its next request when it is ready: dock asks for the active view, then for the other views once painted.visibilitybundle leaves the callback signature. Demand, construction and freezing go throughupdate, freezing as a component withset/add/rmdeltas, and dock keeps paint and its build ledger in its own per-block state.trim_rv()and the internalreactivesclass with the reactives package blockr.core#361), and holds its own per-block state in it.Work
trim_rv()and the internalreactivesclass with the reactives package in blockr.core (Replacetrim_rv()and the internalreactivesclass with the reactives package blockr.core#361)visiblein blockr.core (Render a block when the front-end claims it, not whenvisiblereports it painted blockr.core#366)constructrequests in order and pace them, replacing the background pass, in blockr.core (Buildconstructrequests in the order given, paced by core, instead of a background pass blockr.core#367)updateand drop thevisibilitybundle from the callback signature in blockr.core (Move freezing intoupdateand drop thevisibilitybundle from the callback signature blockr.core#368)visibleandfrozenchannels in blockr.dock: request construction in order, freeze throughupdate, and drop the paint report and the build ledger (Stop driving core'svisibleandfrozenchannels blockr.dock#486)Notes for implementers
Pointers, blockr.core at
366150a:output_render_observer()andrender_gate_observer(),construct_blocks_in_background(),required_fulfilled(), the update gate,insert_block_ui(),is_board_locked(). In blockr.dock atd389603:built_cards(),mark_cards_built()andshow_cards(),freeze_hidden_inputs(),defaultRenderer = "always". Core's own front-end,gate_stacks()and the stack accordion, adopts the same interface as dock.In-flight work: BristolMyersSquibb/blockr.core#337 and BristolMyersSquibb/blockr.dock#420 carry the claim set and move over, with the gate declared at callback registration instead of by writing
visibility$gate(). Ingate_stacks(), the claim payload'sconstructof every collapsed block goes, sinceconstructbuilds all it names in one flush. BristolMyersSquibb/blockr.core#350 and BristolMyersSquibb/blockr.dock#442 are closed as superseded, since the ledger leaves core; whetherboard_ui()paints the opening screen into the page is left to BristolMyersSquibb/blockr.core#317 and BristolMyersSquibb/blockr.dock#438. BristolMyersSquibb/blockr.dock#438 is the dock half of the UI coming with the server. BristolMyersSquibb/blockr.dock#477 moves dock's view registry onto the same reactives collections. BristolMyersSquibb/blockr.core#341 fixes the same render step: keep a merely hidden block's output, and skip re-assigning an identical value.Shiny 1.14 counts an output as hidden only if it or an ancestor has
display: none(isVisible()inshiny.js), and treats one whose state is not yet reported as hidden (shouldSuspend()). Dockview'salwaysrenderer hides a back tab withvisibility: hiddenon the panel'sdv-render-overlay, and a closed Bootstrap.offcanvasisvisibility: hidden; display: flex. Measured on blockr.dockd389603with dockViewR 0.4.0, a back-tab block's output reports.clientdata_output_<id>_hiddenasFALSE. The mock session oftestServer()renders every output, so render gating stays unit-testable only through core's own gate.Shiny's client handles server messages one at a time (
taskQueueinshiny.js) and awaits aninsertUI(), dependencies loaded and inputs bound, before the next. An immediate insert followed by a server'supdate*Input()pushes therefore arrives in order. The insert has to be immediate:insertUI(immediate = TRUE)writes its message at once, while pushes go out with the flush, and a deferred insert is sent throughonFlushed(), after the pushes, which it then misses. Measured with shiny 1.14 in a minimal app, a value pushed in the same flush lands after an immediate insert and is lost after a deferred one. Core'sinsert_block_ui.board()and dock's card insert already passimmediate = TRUE.A payload applies at
priority = -Inf, after the first flush has decided what to construct (measured in BristolMyersSquibb/blockr.core#337). Theupdatechannel is onereactiveVal, so two writes in a flush drop the first, whichfold_update()in BristolMyersSquibb/blockr.dock#420 works around. Theconstructcomponent currently builds every id in the flush that applies it.Freezing a block before its inputs have reported pins blank values for state held in
input$, such as the glue block'stext; dock waits for the card's section report for this reason.Leave room for block code to read demand later (BristolMyersSquibb/blockr.core#240). The exported
validate_board_update()generic dispatches on the board, but the update gate calls the internal validators directly, sovalidate_board_update.dock_board()never runs there; that is BristolMyersSquibb/blockr.core#369.To check before building: the cost of UI with every server on the largest real board (BristolMyersSquibb/blockr.dock#438 measured 91 blocks at 0.5 s and 274 KB), and that dock moves card UI rather than re-creating it. Land #488 first, since it moves the reason a block cannot run out of
output_render_observer().All reactions