Skip to content

Conversation

shikokuchuo
Copy link
Member

@shikokuchuo shikokuchuo commented Aug 7, 2025

Closes #394.

Current behaviour:

  • daemons(n) creates a persistent mirai::daemons span

    • Each daemon() instance also creates a persistent mirai::daemon span
  • mirai() fires a short mirai::mirai client span, which inherits from the active otel span (and links to the mirai::daemons span)

    • Evaluation of the mirai activates a child server span mirai::daemon->eval for the duration of the evaluation (and links to the relevant mirai::daemon span so we know where it ran)
  • daemons(0) ends the persistent spans

Test using:

pak::pak("r-lib/mirai@feat-otel")

library(mirai)
daemons(2)
mp <- mirai_map(1:3, rnorm)
m1 <- mirai(stop("error"))
m2 <- mirai(Sys.sleep(2))
m2[]
daemons(0)

@shikokuchuo shikokuchuo force-pushed the feat-otel branch 4 times, most recently from 3ba64ef to f90d20a Compare August 14, 2025 10:00
@shikokuchuo shikokuchuo force-pushed the feat-otel branch 4 times, most recently from 41027d9 to 13bfe39 Compare August 21, 2025 10:02
if (otel_tracing) {
spn <- otel::start_local_active_span(
"mirai::mirai_map",
links = list(compute_profile = ..[[.compute]][["otel_span"]])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work if .compute is null?

Subsetting a list with a NULL key makes an error. (I don't know what .. is in practice)

❯❯ list(a = 4)[[NULL]]
Error in list(a = 4)[[NULL]] : 
  attempt to select less than one element in get1index

❯❯ list2env(list(a = 4))[[NULL]]
Error in list2env(list(a = 4))[[NULL]] : 
  wrong arguments for subsetting an environment

Comment on lines +118 to +123
if (otel_tracing) {
dmn_spn <- otel::start_local_active_span(
"mirai::daemon",
attributes = otel::as_attributes(list(url = url))
)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From conversations with @atheriel, should we switch the mirai long running daemons to be otel session start/end events?

Then, instead of links, the span would have a session.id attribute pointing to the daemon session.
https://opentelemetry.io/docs/specs/semconv/general/session/

(untested)

          spn <- otel::start_local_active_span(
            "mirai::daemon->eval",
            # links = list(daemon = dmn_spn),
            options = list(kind = "server", parent = prtctx, session.id = dmn_spn$span_id)
          )

Similarly, A session.start and session.end submit events to the active span and spn$add_event().

Maybe this? (untested)

spn <- otel::get_active_span()
spn$add_event("session.start", attributes = list(session.id = url))

And on daemon shutdown:

spn <- otel::get_active_span()
spn$add_event("session.end", attributes = list(session.id = url))

@@ -38,6 +38,7 @@
# tested implicitly

.onLoad <- function(libname, pkgname) {
otel_tracing <<- requireNamespace("otel", quietly = TRUE) && otel::is_tracing_enabled()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My gut reaction is that this value should be dynamic and not fixed.

Motivation: otelsdk::with_otel_record(expr) dynamically turns on tracing, which is useful for testing.

I bet you could reduce it down to a single call. If otel isn't tracing, then store NULL for your span object just flag off of that span value. Then it is only called during the initial creation and not k times throughout the mirai's lifecycle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OpenTelemetry for Observability
2 participants