{"id":29675719,"url":"https://github.com/oxidecomputer/oxide-tokio-rt","last_synced_at":"2025-07-22T23:38:10.752Z","repository":{"id":301248782,"uuid":"1008604609","full_name":"oxidecomputer/oxide-tokio-rt","owner":"oxidecomputer","description":"Shared Tokio runtime configuration for Oxide software","archived":false,"fork":false,"pushed_at":"2025-06-26T21:31:15.000Z","size":35,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-19T23:33:08.867Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oxidecomputer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-25T20:03:03.000Z","updated_at":"2025-06-26T21:31:18.000Z","dependencies_parsed_at":"2025-06-25T23:15:40.707Z","dependency_job_id":"db93c479-a972-4a0f-83e8-c72aa5826b79","html_url":"https://github.com/oxidecomputer/oxide-tokio-rt","commit_stats":null,"previous_names":["oxidecomputer/oxide-tokio-rt"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oxidecomputer/oxide-tokio-rt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Foxide-tokio-rt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Foxide-tokio-rt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Foxide-tokio-rt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Foxide-tokio-rt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oxidecomputer","download_url":"https://codeload.github.com/oxidecomputer/oxide-tokio-rt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Foxide-tokio-rt/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266591230,"owners_count":23953082,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-22T23:38:06.124Z","updated_at":"2025-07-22T23:38:10.726Z","avatar_url":"https://github.com/oxidecomputer.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# oxide-tokio-rt\n\nCommon [Tokio] runtime configuration for Oxide software.\n\n# Overview\n\nTokio's [async runtime][runtime] exposes a variety of configuration options, many of which cannot be set using the [`#\\[tokio::main\\]`] attribute. We have determined that some of these configuration options are generally desirable for production software at Oxide. This crate provides common functions for constructing Tokio runtimes with the recommended configurations.\n\nIn particular, it currently does the following:\n\n- On illumos, configures the runtime to emit DTrace probes, using \n  [`tokio-dtrace`].\n- Disables Tokio's [LIFO slot optimization]. This feature is intended to \n  improve message-passing latency, but because tasks in the LIFO slot do not\n  currently participate in work-stealing, it can result in extreme latency spikes in some cases (see [omicron#8334] for a worked example).\n  \n## When to Use This Crate\n\nIn general, the runtime configuration provided by this crate should be\npreferred for *all production software at Oxide* that uses Tokio. \n\nThe main reason **not** to use this crate is that it requires Tokio's\n[unstable features], as discussed in \n[the following section](#enabling-tokio_unstable_features). Library crates,\nespecially those which we expect will see use outside of Oxide, generally must\ncompile without unstable features enabled. Typically, library crates leave\nruntime construction up to the application, but may use `#[tokio::main]` in\nexamples. In some cases, `#[tokio::main]` may also be used in libraries to\nprovide a blocking interface to an async codebase. If these blocking\ninterfaces are used in production Oxide software, it may be preferable to\nconditionally use `oxide_tokio_rt` rather than `#[tokio::main]` when the\n`tokio_unstable` config flag is set, and use `#[tokio::main]` otherwise.\n\n`cargo xtask`s and other development tools which run on a developer's system\nlocally *may* choose not to use this crate at the author's discretion. This\nmay be preferable if minimizing dependencies improves build time for such\nbinaries.\n\nOf course, at the end of the day, it's your software. If you believe that the\nconfigurations provided by this crate don't benefit your particular use case,\nit may no tbe necessary for you.\n\n# Usage\n\n## Enabling `tokio_unstable` Features\n\nSome of the runtime settings configured by this crate require Tokio's [unstable\nfeatures]. These are features of Tokio that do not yet have stable APIs, and\nmay change in 1.x releases. Unlike other optional features, Tokio requires \nthat only the top-level binary workspace may opt in to these features (i.e.,\n\nthey may not be enabled by library dependencies). This means that the unstable\nfeatures are enabled using a `RUSTFLAGS` config, rather than a Cargo feature.\n\nThe simplest way to enable Tokio's unstable features is to add the\nfollowing to your workspace's `.cargo/config.toml` file:\n\n```toml\n[build]\nrustflags = [\"--cfg\", \"tokio_unstable\"]\n```\n\n\u003cdiv class=\"warning\"\u003e\nThe \u003ccode\u003e[build]\u003c/code\u003e section does \u003cstrong\u003enot\u003c/strong\u003e go in a\n\u003ccode\u003eCargo.toml\u003c/code\u003e file. Instead it must be placed in the Cargo config\nfile \u003ccode\u003e.cargo/config.toml\u003c/code\u003e.\n\u003c/div\u003e\n\nFor more details, see [Tokio's documentation on unstable features][unstable\nfeatures].\n\n### A Warning To `mold` Users\n\nA number of engineers at Oxide use the `mold` linker to improve build times\nin local development. Often, `cargo` is configured to use `mold` via a global\n`RUSTFLAGS` setting in `~/.cargo/config.toml`. If you're using this crate,\n**you gotta stop doing it that way**, as the global `RUSTFLAGS` configuration\nwill interfere with workspace-local `RUSTFLAGS` configurations required to\nenable `tokio_unstable`. `.cargo/config.toml` settings are **not additive**.\n\nInstead, consider using `mold -run cargo` to build with `mold`, as described [here][mold-run].\n\n## Replacing `#[tokio::main]`\n\nTo replace basic uses of `#[tokio::main]` with no additional options, use\nthe `oxide_tokio_rt::run` function in a non-async `fn main()`.  \n\nFor example, consider the following `main` function:\n\n```rust\n#[tokio::main]\nasync fn main() {\n    // ... actually do async stuff ...\n}\n```\n\nUsing `oxide_tokio_rt::run()`, this becomes the following:\n\n```rust\nfn main() {\n    oxide_tokio_rt::run(async {\n        // ... actually do async stuff ...\n    })  \n}\n```\n\nWhen additional configuration of the runtime is required, the\n`oxide_tokio_rt::run_builder()` function takes a [`tokio::runtime::Builder`] as\nan argument, and applies the common configurations to that builder before\nusing it to construct the runtime.\n\nFor example, if we are setting the number of worker threads in the \n`#[tokio::main]` macro, like this:\n\n```rust\n#[tokio::main(worker_threads = 10)]\nasync fn main() {\n    // ... actually do async stuff ...\n}\n```\n\n...we can use `run_builder()` to configure the runtime to have 10 worker\nthreads, like this:\n\n```rust\nfn main() {\n    // `oxide-tokio-rt` re-exports theTtokio runtime builder type.\n    let mut builder = oxide_tokio_rt::Builder::new_multi_thread();\n    // Set the desired number of worker threads to 10.\n    builder.worker_threads(10);\n    \n    // Run the application using the configured builder.\n    oxide_tokio_rt::run_builder(\u0026mut builder, async {\n        // ... actually do async stuff ...\n    })\n}\n```\n\nNote that `oxide_tokio_rt::run` will construct a \n[multi-threaded Tokio runtime][rt-mt], and therefore requires the \n`\"rt-multi-thread\"` feature flag. This feature flag is enabled by default. If\nan application requires a  single-threaded Tokio runtime, instead, first\ndisable the \"`rt-multi-thread\"` feature in your `Cargo.toml`:\n\n```toml\n[dependencies.oxide-tokio-rt]\ngit = \"https://github.com/oxidecomputer/oxide-tokio-rt\"\ndefault-features = false\n```\n\n...and then use `oxide_tokio_rt::run_builder()` with the builder returned by\n[`tokio::runtime::Builder::new_current_thread()`][new-current], like so:\n\n```rust\nfn main() {\n    oxide_tokio_rt::run_builder(\u0026mut\n        oxide_tokio_rt::Builder::new_current_thread(),\n        async {\n            // ... actually do async stuff ...\n        })\n}\n```\n\n## Warning on Use of `#[tokio::main]`\n\n[Clippy]'s [`disallowed_macros`] lint can be used to configure Clippy to emit\na warning when the `#[tokio::main]` attribute is used, to ensure that\n`oxide_tokio_rt` is used instead. This is particularly useful in workspaces\nthat contain a large number of binaries, such as Omicron, to prevent\ndevelopers from forgetting to use this crate when adding new binaries.\n\nAdding the following to `clippy.toml` in the root of the workspace will cause Clippy to warn when `#[tokio::main]` is used.\n\n```toml\n[[disallowed-macros]]\npath = \"tokio::main\"\nreason = \"prefer `oxide_tokio_rt` for production software\"\nreplacement = \"oxide_tokio_rt::run\"\n```\n\n[Intentional uses of `#[tokio::main]`](#when-to-use-this-crate) in a workspace\nthat enables this lint can be annotated with \n`#[expect(clippy::disallowed_macros)]`, ideally along with a `reason` string\nexplaining why `#[tokio::main]` is in use. For example:\n\n```rust\n#[expect(\n    clippy::disallowed_macros,\n    reason = \"this is an example\",\n)]\n#[tokio::main]\nasync fn main() {\n    // ...\n}\n```\n\n[Tokio]: https://tokio.rs\n[runtime]: https://docs.rs/tokio/latest/tokio/runtime/index.html\n[`#\\[tokio::main\\]`]: https://docs.rs/tokio/latest/tokio/attr.main.html\n[`tokio-dtrace`]: https://github.com/oxidecomputer/tokio-dtrace\n[LIFO slot optimization]: https://docs.rs/tokio/latest/tokio/runtime/struct.Builder.html#method.disable_lifo_slot\n[omicron#8334]: https://github.com/oxidecomputer/omicron/issues/8334#issuecomment-2993159283\n[unstable features]: https://docs.rs/tokio/latest/tokio/#unstable-features\n[rt-mt]: https://docs.rs/tokio/latest/tokio/runtime/struct.Builder.html#method.new_multi_thread\n[`tokio::runtime::Builder`]: https://docs.rs/tokio/latest/tokio/runtime/struct.Builder.html\n[new-current]: https://docs.rs/tokio/latest/tokio/runtime/struct.Builder.html#method.new_current_thread\n[Clippy]: https://github.com/rust-lang/rust-clippy\n[`disallowed_macros`]: https://rust-lang.github.io/rust-clippy/master/#disallowed_macros\n[mold-run]: https://github.com/rui314/mold#how-to-use\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxidecomputer%2Foxide-tokio-rt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foxidecomputer%2Foxide-tokio-rt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxidecomputer%2Foxide-tokio-rt/lists"}