//! 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::Builder::new_multi_thread() .worker_threads(1) .enable_io() .enable_time() .build() }