Skip to content

4b: Replace #[tokio::main] with manual tokio::runtime::Builder #249

Description

@ajianaz

Parent: #234 · Blocked by: #248

Scope

Replace #[tokio::main] with manual tokio::runtime::Builder in both Rungu (rungud/src/main.rs) and CIRA main entry point. Required because sentry::init() must be called before the tokio runtime is created.

Why This Change?

#[tokio::main] expands to fn main() { tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(async { ... }) }.

Sentry's init() sets up the global guard which needs to be active before any async code runs. The macro doesn't give us a place to inject sentry::init() before the runtime starts.

Before (Rungu example)

#[tokio::main]
async fn main() {
    // sentry::init() here is "too late" — runtime already created
    sentry::init(sentry::ClientOptions {
        dsn: config.sentry.dsn.clone(),
        ..Default::default()
    });
    
    let app = create_app().await;
    // ...
}

After

fn main() {
    let _sentry_guard = sentry::init(sentry::ClientOptions {
        dsn: config.sentry.dsn.clone(),
        release: sentry::release_name!(),
        environment: Some(config.sentry.environment.clone().into()),
        ..Default::default()
    });
    
    // Sentry guard must stay alive for the process lifetime
    // The _sentry_guard must NOT be dropped
    
    let runtime = tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .thread_name("rungu-worker")
        .build()
        .expect("Failed to create tokio runtime");
    
    runtime.block_on(async_main(config));
}

Tasks

  • Refactor rungud/src/main.rs: remove #[tokio::main], add manual runtime
  • Refactor CIRA main entry: same pattern
  • Move async logic to async fn async_main() helper
  • Ensure _sentry_guard lives until end of main() (not dropped early)
  • Test: cargo run starts normally without DSN (guard = noop)
  • Test: cargo run with DSN → Sentry initialized before any request
  • Verify no runtime warnings or deadlocks

Risk

Risk Mitigation
_sentry_guard dropped early → no events captured Keep as let _guard at function scope (lives until main exits)
Thread name conflicts Use descriptive names: rungu-worker, cira-worker
Runtime config mismatch Mirror the default #[tokio::main] behavior: multi_thread + enable_all

Effort: ~1 hour

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestscope:sdkSentry SDK integration in client apps (Rungu/CIRA)type:envelopeSentry envelope item type expansion

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions