Skip to content

TraceProvider::with_exporter immediately drops BatchSpanProcessor #225

Closed
@frigus02

Description

@frigus02

While testing #224, I came across an issue.

Steps to reproduce

  1. Checkout the PR (at the point of writing ffa96df).
  2. Open examples/stdout.rs and change:
    + #[tokio::main]
    + async fn main() {
    - fn main() {
  3. Run cargo run --example stdout and observe the span being printed to the console.
  4. Run cargo run --example stdout --features tokio and observe that nothing is printed. With the tokio feature enabled it used the BatchSpanProcessor setup by TraceProvider::with_exporter.

Analysis

I reproduced it on master as well and with a few print statements found that the BatchSpanProcessorWorker is immediately dropped after calling with_exporter.

See my experiments here: 13fc775

The reason is that with_exporter uses either tokio::task::spawn_blocking or async_std::task::spawn_blocking (see sdk::TraceProvider). Both of those expect a blocking function, not a function returning a future. This means the BatchSpanProcessorWorker is never polled.

Possible solution

I assume the reason for using spawn_blocking is that the exporters currently run blocking, so it's good to run on a special thread for blocking work. The solution for the problem then is most likely to execute the future using block_on:

let spawn = |future| {
    tokio::task::spawn_blocking(|| {
        futures::executor::block_on(future);
        // or tokio::runtime::Handle::current().block_on(future)
        // or async_std::task::block_on(future)
    })
};
let batch = sdk::BatchSpanProcessor::builder(exporter, spawn, async_std::stream::interval);

If I do this, however, the program never exits. You can test this with the above linked example. The BatchSpanProcessorWorker just keeps running because it does never receive a shotdown message.

I'm not sure why, yet. I think the provider should be dropped and then notify all registered span processors. But that does not seem to happen.

If I manually call shutdown for all span processors, the worker stops properly, exports the remaining spans, and then the program exits.

I'm happy to work on a fix, but I would like to hear your thoughts first. What's the best way to proceed here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions