Skip to content

Commit 7330155

Browse files
committed
streamline Shiny vignette
1 parent c9c37c0 commit 7330155

File tree

1 file changed

+14
-38
lines changed

1 file changed

+14
-38
lines changed

vignettes/shiny.Rmd

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@ knitr::opts_chunk$set(
1717

1818
`mirai` may be used as an asynchronous / distributed backend to scale [Shiny](https://shiny.posit.co/) applications.
1919

20-
Depending on the options suppled to `daemons()`, tasks may be distributed across local background processes or multiple networked servers in an efficient and performant manner.
20+
Depending on the options suppled to `daemons()`, mirai tasks may be distributed across local background processes or multiple networked servers in an efficient and performant manner.
21+
2122

2223
#### Shiny ExtendedTask Example: Clock and Plot
2324

24-
'mirai' may be used within Shiny's ExtendedTask framework to create scalable Shiny apps, which are more responsive for a single user, as well as for multiple concurrent users. 'mirai' are accepted anywhere a 'promise', 'future' or 'future_promise' is currently accepted.
25+
mirai may be used within Shiny's ExtendedTask framework (in `shiny` >= 1.8.1) to create scalable Shiny apps, which are more responsive for a single user, as well as for multiple concurrent users.
2526

26-
The examples below requires Shiny >= 1.8.1 and promises >= 1.3.0.
27+
'mirai' are accepted anywhere a 'promise', 'future' or 'future_promise' is currently accepted (with `promises` >= 1.3.0).
2728

28-
Importantly, the app remains responsive, as shown by the clock continuing to tick whilst the simulated expensive computation is running. Also the button is disabled and the plot greyed out until the computation is complete.
29+
In the example below, the app remains responsive, with the clock continuing to tick whilst the simulated expensive computation is running. Also the button is disabled and the plot greyed out until the computation is complete.
2930

30-
By wrapping the `runApp()` call in `with(daemons(...), ...)` this conveniently configures the daemons for the duration of the app, and they automatically exit when the app is stopped.
31+
By wrapping the `runApp()` call in `with(daemons(...), ...)` the daemons are set up for the duration of the app, exiting automatically when the app is stopped.
3132

3233
```{r shinyextended, eval=FALSE}
3334
library(shiny)
@@ -75,25 +76,26 @@ The key components to using ExtendedTask are:
7576
input_task_button("btn", "Plot uniform distribution")
7677
```
7778

78-
2. In the server, create an 'ExtendedTask' object by calling `ExtendedTask$new()` on a function which is a call to `mirai()`, and optionally bind it to the button created in (1).
79+
2. In the server, create an 'ExtendedTask' object by calling `ExtendedTask$new()` on a function which is a call to `mirai()`, and optionally bind it to the button created in (1). Remember to pass in any custom functions or variables as `...` or `.args` arguments to `mirai()`.
7980

8081
```{r shinystep2, eval=FALSE}
8182
extended_task <- ExtendedTask$new(
8283
function(x, y) mirai({Sys.sleep(y); runif(x)}, x = x, y = y)
8384
) |> bind_task_button("btn")
8485
```
85-
3. In the server, create an observer on the input button, which invokes the 'ExtendedTask' object with the appropriate inputs.
86+
3. In the server, create an observer on the input button, which invokes the 'ExtendedTask' object with the required parameters.
8687

8788
```{r shinystep3, eval=FALSE}
8889
observeEvent(input$btn, extended_task$invoke(input$n, input$delay))
8990
```
9091

9192
4. In the server, create a render function for the output plot, which consumes the result of the 'ExtendedTask' object.
92-
`
93+
9394
```{r shinystep4, eval=FALSE}
9495
output$plot <- renderPlot(hist(extended_task$result()))
9596
```
9697

98+
9799
#### Shiny ExtendedTask Example: Generative Art
98100

99101
The following app produces pretty spiral patterns.
@@ -180,40 +182,14 @@ with(daemons(3), runApp(app))
180182
```
181183
*The above example builds on original code by Joe Cheng, Daniel Woodie and William Landau.*
182184

183-
Again, the key components to using ExtendedTask are:
184-
185-
1. In the UI, use `bslib::input_task_button()`. This is optional, but automates the button being disabled during computation.
186-
187-
```{r shinystep21, eval=FALSE}
188-
input_task_button(ns("resample"), "Resample")
189-
```
190-
191-
2. In the server, create an 'ExtendedTask' object by calling `ExtendedTask$new()` on a function which is a call to `mirai()`, and optionally bind it to the button created in (1). In this example, as `run_task()` is defined outside of a package, it is passed along with its parameters as arguments to `mirai()`.
192-
193-
```{r shinystep22, eval=FALSE}
194-
extended_task <- ExtendedTask$new(
195-
function(x) mirai(run_task(calc_time = x), .args = list(run_task, x))
196-
) |> bind_task_button("resample")
197-
```
198-
3. In the server, create an observer on the input button, which invokes the 'ExtendedTask' function with the required parameters.
199-
200-
```{r shinystep23, eval=FALSE}
201-
observeEvent(input$resample, extended_task$invoke(calc_time))
202-
```
203-
204-
4. In the server, create a render function for the output plot, which consumes the result of the 'ExtendedTask' object.
205-
`
206-
```{r shinystep24, eval=FALSE}
207-
output$plot <- renderPlot(plot_result(extended_task$result()))
208-
```
209185

210-
#### Advanced Non-Promise Example
186+
#### Advanced Non-Promise Example: Generative Art
211187

212-
Whilst it is generally recommended to use the ExtendedTask framework, it is also possible for 'mirai' to plug directly into the reactive framework, without the use of 'promises' (implicitly or explicitly). This may be required for advanced uses of asynchronous programming.
188+
Whilst it is generally recommended to use the ExtendedTask framework, it is also possible for mirai to plug directly into Shiny's reactive framework, without the use of 'promises' either implicitly or explicitly. This may be required for advanced uses of asynchronous programming, or where the use case does not fit the semantics of ExtendedTask.
213189

214-
The following is similar to the previous example. There is a button to submit tasks, which will be processed by one of 3 daemons, outputting a pretty spiral pattern upon completion. If more than 3 tasks are submitted at once, the chart updates 3 at a time, limited by the number of available daemons.
190+
The following is similar to the previous example, but allows multiple tasks to be submitted at once, rather than one after the other as required by ExtendedTask. There is a button to submit tasks, which will be processed by one of 3 daemons, outputting a pretty spiral pattern upon completion. If more than 3 tasks are submitted at once, the chart updates 3 at a time, limited by the number of available daemons.
215191

216-
It can be seen that more boilerplate code is required to manage the 'mirai' tasks, but it otherwise functions similarly to the ExtendedTask example.
192+
It requires more boilerplate code to manage the mirai tasks, but otherwise functions similarly to the ExtendedTask example.
217193

218194
```{r shiny, eval=FALSE}
219195
library(mirai)

0 commit comments

Comments
 (0)