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
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
Parent: #234 · Blocked by: #248
Scope
Replace
#[tokio::main]with manualtokio::runtime::Builderin both Rungu (rungud/src/main.rs) and CIRA main entry point. Required becausesentry::init()must be called before the tokio runtime is created.Why This Change?
#[tokio::main]expands tofn 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 injectsentry::init()before the runtime starts.Before (Rungu example)
After
Tasks
rungud/src/main.rs: remove#[tokio::main], add manual runtimeasync fn async_main()helper_sentry_guardlives until end ofmain()(not dropped early)cargo runstarts normally without DSN (guard = noop)cargo runwith DSN → Sentry initialized before any requestRisk
_sentry_guarddropped early → no events capturedlet _guardat function scope (lives until main exits)rungu-worker,cira-worker#[tokio::main]behavior: multi_thread + enable_allEffort: ~1 hour