35 lines
1.6 KiB
Rust
35 lines
1.6 KiB
Rust
//! The tokio runtime every network worker is built from.
|
|
//!
|
|
//! One function rather than a builder repeated at each call site, because the
|
|
//! choice it encodes is not obvious and was wrong in eleven places at once.
|
|
//!
|
|
//! **Why not `new_current_thread`.** A current-thread runtime drives its
|
|
//! reactor only while the thread is inside `block_on`. On Android that left
|
|
//! reqwest's connection future unpolled: the await never resolved, so the
|
|
//! worker neither failed nor returned. Every symptom was an absence — no error,
|
|
//! no panic for `catch_unwind` to catch, no log line, and a channel that closed
|
|
//! only when the thread was finally torn down. What the user saw was a sign-in
|
|
//! that stopped, and a library that quietly scanned itself rather than adopting
|
|
//! the shards the server already held.
|
|
//!
|
|
//! A multi-thread runtime owns worker threads that poll the reactor regardless.
|
|
//! One worker is enough: these are single request-response flows, not
|
|
//! throughput-bound work.
|
|
//!
|
|
//! **Why not `enable_all`.** That also starts the signal driver, which wants
|
|
//! process-wide signal handling. Inside an Android app the runtime already owns
|
|
//! that, and a worker thread claiming it is asking for trouble. These flows need
|
|
//! IO (reqwest) and time (poll intervals, timeouts) and nothing else.
|
|
|
|
/// Build a runtime suitable for a network worker thread.
|
|
///
|
|
/// Call from the spawned thread, not from the caller: the runtime must live on
|
|
/// the thread that blocks on it.
|
|
pub fn build() -> std::io::Result<tokio::runtime::Runtime> {
|
|
tokio::runtime::Builder::new_multi_thread()
|
|
.worker_threads(1)
|
|
.enable_io()
|
|
.enable_time()
|
|
.build()
|
|
}
|