Async runtime for Rust with task scheduling, I/O, and timers.
// Full runtime with all features
#[tokio::main]
async fn main() {
// Your async code
}
// Custom runtime configuration
#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() { }
// Current-thread runtime (single-threaded)
#[tokio::main(flavor = "current_thread")]
async fn main() { }
use tokio::task;
// Spawn async task
let handle = tokio::spawn(async {
// Background work
expensive_computation().await
});
// Wait for result
let result = handle.await?;
// Spawn blocking task (CPU-bound work)
let result = task::spawn_blocking(|| {
// Blocking/CPU-intensive code
compute_hash(data)
}).await?;
// Detached task (fire and forget)
tokio::spawn(async {
log_event(event).await;
});
use tokio::{select, join, time};
// Run multiple futures concurrently
let (a, b, c) = join!(task_a(), task_b(), task_c());
// Race futures, cancel losers
select! {
result = fetch_primary() => handle_primary(result),
result = fetch_backup() => handle_backup(result),
_ = time::sleep(Duration::from_secs(5)) => timeout_error(),
}
// Timeout wrapper
let result = time::timeout(
Duration::from_secs(30),
long_running_task()
).await?;
use tokio::sync::{Mutex, RwLock, mpsc, broadcast, oneshot};
// Async mutex (allows holding across await)
let data = Arc::new(Mutex::new(vec![]));
{
let mut guard = data.lock().await;
guard.push(item);
}
// RwLock for read-heavy workloads
let cache = Arc::new(RwLock::new(HashMap::new()));
let value = cache.read().await.get(&key);
// Channels
let (tx, mut rx) = mpsc::channel(100);
tx.send(message).await?;
while let Some(msg) = rx.recv().await {
process(msg);
}
// Oneshot for single response
let (tx, rx) = oneshot::channel();
tokio::spawn(async move { tx.send(result) });
let response = rx.await?;
use tokio::{fs, io::{AsyncReadExt, AsyncWriteExt}, net::TcpListener};
// File I/O
let content = fs::read_to_string("file.txt").await?;
fs::write("output.txt", data).await?;
// TCP server
let listener = TcpListener::bind("127.0.0.1:8080").await?;
loop {
let (socket, _) = listener.accept().await?;
tokio::spawn(handle_connection(socket));
}
// Buffered I/O
use tokio::io::{BufReader, BufWriter};
let reader = BufReader::new(file);
let mut lines = reader.lines();
while let Some(line) = lines.next_line().await? {
process(line);
}
use tokio::signal;
async fn shutdown_signal() {
let ctrl_c = async {
signal::ctrl_c().await.expect("Failed to install Ctrl+C handler");
};
#[cfg(unix)]
let terminate = async {
signal::unix::signal(signal::unix::SignalKind::terminate())
.expect("Failed to install SIGTERM handler")
.recv()
.await;
};
#[cfg(not(unix))]
let terminate = std::future::pending::<()>();
tokio::select! {
_ = ctrl_c => {},
_ = terminate => {},
}
}
spawn_blocking for CPU-bound or blocking I/OJoinHandle::await? to propagate panicstokio-console for debugging async issuesSearch for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer