m07-concurrency_skill

This skill helps you design and reason about Rust concurrency, choosing appropriate primitives and avoiding deadlocks.
  • Shell

565

GitHub Stars

2

Bundled Files

2 months ago

Catalog Refreshed

4 months ago

First Indexed

Readme & install

Copy the install command, review bundled files from the catalogue, and read any extended description pulled from the listing source.

Installation

Preview and clipboard use veilstrat where the catalogue uses aiagentskills.

npx veilstrat add skill zhanghandong/rust-skills --skill m07-concurrency

  • comparison.md7.3 KB
  • SKILL.md6.2 KB

Overview

This skill guides Rust developers through concurrency and async decisions, error diagnosis, and safe implementations. It helps determine whether to use threads, async, or message passing, and shows how to trace errors like E0277 to design constraints before applying fixes. It emphasizes domain-aware choices and avoiding common anti-patterns.

How this skill works

It inspects error contexts and workload characteristics to recommend appropriate primitives (std::thread, rayon, tokio, channels, Arc/Mutex/RwLock, atomics). It traces UP to domain constraints (web, CLI, fintech, cloud-native) to decide thread-safety requirements and traces DOWN to map design choices to concrete implementations. It provides patterns for avoiding deadlocks, holding locks across await points, and handling non-Send/!Sync types.

When to use it

  • When you see E0277 Send/Sync or "future is not Send" errors
  • When deciding between CPU-bound parallelism and I/O-bound async
  • When sharing data across threads or tasks
  • When diagnosing deadlocks, race conditions, or contention
  • When migrating single-threaded code (Rc/RefCell) to multi-threaded contexts

Best practices

  • Classify workload: CPU-bound → threads/rayon; I/O-bound → async/await (tokio)
  • Trace UP to domain constraints before changing types or adding bounds
  • Prefer message passing (channels) when no shared mutable state is needed
  • Use Arc<T> for immutable shared data; Arc<Mutex<T>> or Arc<RwLock<T>> for mutable sharing, but minimize scope of locks
  • Avoid holding Mutex/RwLock guards across .await; drop guards before awaiting
  • Use spawn_blocking for CPU work in async runtimes and spawn_local only for truly non-Send futures

Example use cases

  • Fixing "Rc cannot be sent between threads" in a web handler by tracing to domain-web and switching to Arc<AppState>
  • Resolving "future is not Send" by dropping non-Send values before await or using spawn_local on a single-thread runtime
  • Choosing rayon or thread::spawn for CPU-heavy batch processing, with atomics for simple counters
  • Replacing global Arc<Mutex<T>> contention with channel-based message passing in a high-concurrency service
  • Preventing deadlock by enforcing consistent lock ordering and using try_lock for diagnostics

FAQ

No. Ask whether the type actually needs to cross thread boundaries. Tracing the domain and ownership model can show that single-threaded or spawn_local solutions are more appropriate.

When do I prefer channels over locks?

Use channels when components can exchange messages without shared mutable state. Channels reduce contention and often simplify reasoning compared to pervasive Arc<Mutex<T>>.

How do I handle non-Send types in async code?

Either convert to Send-safe types (Arc instead of Rc), ensure non-Send values are dropped before await, or run the task on a single-threaded runtime with spawn_local.

Built by
VeilStrat
AI signals for GTM teams
© 2026 VeilStrat. All rights reserved.All systems operational
m07-concurrency skill by zhanghandong/rust-skills | VeilStrat