Nothing
# devtools::load_all(); dev_otel_kitchen()
dev_otel_kitchen <- function() {
library(mirai)
mirai::daemons(2)
# Inspiration from
# * https://github.com/r-lib/otel/commit/a2ef493ae4b97701e4e178ac527f313580539080
# * https://github.com/r-lib/otel/commit/09c0eb6c80d5b907976de8fbaf89798cb11f8e6e#diff-169b8f234d0b208affb106fce375f86fefe2f16dba4ad66495a1dc06c8a4cd7b
otel_logger <- otel::get_logger("my-app-logger")
otel_tracer_name <- "my-app"
log_and_msg <- function(..., .envir = parent.frame()) {
msg <- paste(...)
message(" -- ", msg)
otel_log(msg, logger = otel_logger)
}
my_global_reactive <- reactiveVal(0)
app <- shinyApp(
ui = fluidPage(
sliderInput("mymod-x", "x", 1, 10, 5),
sliderInput("mymod-y", "y", 1, 10, 5),
div("x * y: "),
verbatimTextOutput("mymod-txt1"),
verbatimTextOutput("mymod-txt2"),
verbatimTextOutput("mymod-txt3"),
verbatimTextOutput("task_result")
),
server = function(input, output, session) {
log_and_msg("Start new Shiny session")
b <- reactiveVal(1)
observe(b(42))
shutdown <- function() {
later::later(
function() {
message("\n\nClosing session for minimal logfire graphs")
# session$close()
# httpuv::stopAllServers()
stopApp()
mirai::daemons(0)
},
delay = 100 / 1000
)
}
later::later(
function() {
if (!session$closed) {
log_and_msg("Invoking shutdown after 5s")
shutdown()
}
},
delay = 5
)
xMod <- function(id) {
moduleServer(id, function(input, output, session) {
xVal <- reactiveVal(NULL)
yVal <- reactiveVal(NULL)
rv <- reactiveValues(x = NULL, y = NULL)
log_and_msg("Shiny module")
x_raw <- reactive({
isolate({
my_global_reactive(my_global_reactive() + 1)
})
x_val <- xVal()
req(x_val)
log_and_msg(sprintf("X Val: %s", x_val))
x_val
})
x <- debounce(x_raw, 100)
y_raw <- reactive({
y_val <- input$y
log_and_msg(sprintf("Y Val: %s", y_val))
# Sys.sleep(0.5)
y_val
}) |> bindCache(input$y) |> bindEvent(input$y)
y <- throttle(y_raw, 100)
calc <- reactive(label = "barret_calc", {
log_and_msg("Doing expensive computation...")
x() * y()
})
observe({
log_and_msg("x: ", x())
})
output$txt1 <- renderText({
calc()
}) |>
bindCache(x(), y())
output$txt2 <- renderText({
calc()
}) |>
bindEvent(list(x(), y()))
output$txt3 <- renderText({
calc()
}) |>
bindCache(x(), y()) |>
bindEvent(list(x(), y()))
rand_task <- ExtendedTask$new(function() {
mirai::mirai(
{
# Slow operation goes here
Sys.sleep(100 / 1000)
sample(1:100, 1)
}
)
})
observeEvent(input$x, {
# Invoke the extended in an observer
rand_task$invoke()
}, label = "invoke_rand_task")
output$task_result <- renderText({
# React to updated results when the task completes
number <- rand_task$result()
paste0("Your number is ", number, ".")
})
mydesc <- reactiveFileReader(
1000,
session,
filePath = system.file("DESCRIPTION", package = "shiny"),
readFunc = read.dcf
)
observe({
mydesc()
})
myfile <- reactivePoll(
1000,
session,
checkFunc = function() {
Sys.time()
},
# This function returns the content of log_file
valueFunc = function() {
read.dcf(system.file("DESCRIPTION", package = "shiny"))
}
)
observe({
myfile()
})
x_prom <- reactive({
# t0
x_span_id <- force(otel::get_active_span_context()$get_span_id())
# message("x_prom span id: ", x_span_id)
x_val <- x()
log_and_msg("x_prom init")
p <- promises::promise(function(resolve, reject) {
log_and_msg("x_prom 0")
resolve(x_val)
})
p <- promises::then(p, function(x_val) {
log_and_msg("x_prom 1")
log_and_msg("Launching mirai")
x_val
# mirai::mirai_map(seq_len(x_val), function(i) {
# otel::start_local_active_span("slow compute")
# Sys.sleep(i / 10 / 1000)
# i
# }) |>
# promises::then(function(vals) {
# max(unlist(vals))
# })
# mirai::mirai(
# {
# otel::start_local_active_span("slow compute")
# # val
# # Sys.sleep(0.2)
# val
# },
# val = x_val
# )
})
p <- promises::then(p, function(x_val) {
log_and_msg("x_prom 2")
x_val
})
p <- promises::then(p, function(x_val) {
log_and_msg("x_prom 3")
x_val
})
})
y_prom <- reactive({
y_span_id <- force(otel::get_active_span_context()$get_span_id())
# message("y_prom span id: ", y_span_id)
y_val <- y()
log_and_msg("y_prom init")
yp <- promises::promise(function(resolve, reject) {
log_and_msg("y_prom 0")
resolve(y_val)
})
log_and_msg("make y_prom 1")
yp <- promises::then(yp, function(y_val) {
log_and_msg("y_prom 1")
y_val
})
log_and_msg("make y_prom 2")
yp <- promises::then(yp, function(y_val) {
log_and_msg("y_prom 2")
y_val + calc()
})
log_and_msg("make y_prom 3")
yp <- promises::then(yp, function(y_val) {
log_and_msg("y_prom 3")
y_val
})
log_and_msg(
"done y_prom - ",
getCurrentContext()$id,
" - ",
getCurrentContext()$.label
)
yp
})
observe(label = "proms_observer", {
p <- promises::promise_all(
x_prom(),
y_prom()
)
p <- promises::then(p, function(vals) {
log_and_msg("Vals[1]: ", vals[[1]])
log_and_msg("Vals[2]: ", vals[[2]])
# cat(force)
# Shut down the app so the telemetry can be seen easily
if (vals[[1]] < 6) {
updateSliderInput(
"x",
value = vals[[1]] + 1,
session = session
)
} else {
shutdown()
}
})
log_and_msg(
"done proms_observer - ",
getCurrentContext()$id,
" - ",
getCurrentContext()$.label
)
p
})
# |>
# bindOtel()
# Set the value late in the reactive calc
observeEvent(
{
input$x
},
{
rv$x <- input$x
},
label = "singleObserveEvent"
)
tmp_val <- reactiveVal(NULL)
# TODO: Not recording updates within the span!!
x_calc <- eventReactive(
{
isolate(tmp_val(1))
rv$x
},
{
tmp_val(2)
rv$x
}
)
y_calc <- eventReactive(
{
isolate(tmp_val(3))
input$y * 2
},
{
# x_calc()
tmp_val(4)
input$y * 2 / 2
}
)
# observeEvent(label = "set_y", {
# rv$y <- input$y
# })
observe(label = "set xVal", {
x_calc()
xVal(rv$x)
})
observe(label = "set yVal", {
yVal(y_calc())
})
})
}
xMod("mymod")
}
)
app
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.