npx skills add https://github.com/zhanghandong/rust-skills --skill m07-concurrencyHow M07 Concurrency fits into a Paperclip company.
M07 Concurrency drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.
Pre-configured AI company — 18 agents, 18 skills, one-time purchase.
SKILL.md222 linesExpandCollapse
---name: m07-concurrencydescription: "CRITICAL: Use for concurrency/async. Triggers: E0277 Send Sync, cannot be sent between threads, thread, spawn, channel, mpsc, Mutex, RwLock, Atomic, async, await, Future, tokio, deadlock, race condition, 并发, 线程, 异步, 死锁"user-invocable: false--- # Concurrency > **Layer 1: Language Mechanics** ## Core Question **Is this CPU-bound or I/O-bound, and what's the sharing model?** Before choosing concurrency primitives:- What's the workload type?- What data needs to be shared?- What's the thread safety requirement? --- ## Error → Design Question | Error | Don't Just Say | Ask Instead ||-------|----------------|-------------|| E0277 Send | "Add Send bound" | Should this type cross threads? || E0277 Sync | "Wrap in Mutex" | Is shared access really needed? || Future not Send | "Use spawn_local" | Is async the right choice? || Deadlock | "Reorder locks" | Is the locking design correct? | --- ## Thinking Prompt Before adding concurrency: 1. **What's the workload?** - CPU-bound → threads (std::thread, rayon) - I/O-bound → async (tokio, async-std) - Mixed → hybrid approach 2. **What's the sharing model?** - No sharing → message passing (channels) - Immutable sharing → Arc<T> - Mutable sharing → Arc<Mutex<T>> or Arc<RwLock<T>> 3. **What are the Send/Sync requirements?** - Cross-thread ownership → Send - Cross-thread references → Sync - Single-thread async → spawn_local --- ## Trace Up ↑ (MANDATORY) **CRITICAL**: Don't just fix the error. Trace UP to find domain constraints. ### Domain Detection Table | Context Keywords | Load Domain Skill | Key Constraint ||-----------------|-------------------|----------------|| Web API, HTTP, axum, actix, handler | **domain-web** | Handlers run on any thread || 交易, 支付, trading, payment | **domain-fintech** | Audit + thread safety || gRPC, kubernetes, microservice | **domain-cloud-native** | Distributed tracing || CLI, terminal, clap | **domain-cli** | Usually single-thread OK | ### Example: Web API + Rc Error ```"Rc cannot be sent between threads" in Web API context ↑ DETECT: "Web API" → Load domain-web ↑ FIND: domain-web says "Shared state must be thread-safe" ↑ FIND: domain-web says "Rc in state" is Common Mistake ↓ DESIGN: Use Arc<T> with State extractor ↓ IMPL: axum::extract::State<Arc<AppConfig>>``` ### Generic Trace ```"Send not satisfied for my type" ↑ Ask: What domain is this? Load domain-* skill ↑ Ask: Does this type need to cross thread boundaries? ↑ Check: m09-domain (is the data model correct?)``` | Situation | Trace To | Question ||-----------|----------|----------|| Send/Sync in Web | **domain-web** | What's the state management pattern? || Send/Sync in CLI | **domain-cli** | Is multi-thread really needed? || Mutex vs channels | m09-domain | Shared state or message passing? || Async vs threads | m10-performance | What's the workload profile? | --- ## Trace Down ↓ From design to implementation: ```"Need parallelism for CPU work" ↓ Use: std::thread or rayon "Need concurrency for I/O" ↓ Use: async/await with tokio "Need to share immutable data across threads" ↓ Use: Arc<T> "Need to share mutable data across threads" ↓ Use: Arc<Mutex<T>> or Arc<RwLock<T>> ↓ Or: channels for message passing "Need simple atomic operations" ↓ Use: AtomicBool, AtomicUsize, etc.``` --- ## Send/Sync Markers | Marker | Meaning | Example ||--------|---------|---------|| `Send` | Can transfer ownership between threads | Most types || `Sync` | Can share references between threads | `Arc<T>` || `!Send` | Must stay on one thread | `Rc<T>` || `!Sync` | No shared refs across threads | `RefCell<T>` | ## Quick Reference | Pattern | Thread-Safe | Blocking | Use When ||---------|-------------|----------|----------|| `std::thread` | Yes | Yes | CPU-bound parallelism || `async/await` | Yes | No | I/O-bound concurrency || `Mutex<T>` | Yes | Yes | Shared mutable state || `RwLock<T>` | Yes | Yes | Read-heavy shared state || `mpsc::channel` | Yes | Optional | Message passing || `Arc<Mutex<T>>` | Yes | Yes | Shared mutable across threads | ## Decision Flowchart ```What type of work?├─ CPU-bound → std::thread or rayon├─ I/O-bound → async/await└─ Mixed → hybrid (spawn_blocking) Need to share data?├─ No → message passing (channels)├─ Immutable → Arc<T>└─ Mutable → ├─ Read-heavy → Arc<RwLock<T>> └─ Write-heavy → Arc<Mutex<T>> └─ Simple counter → AtomicUsize Async context?├─ Type is Send → tokio::spawn├─ Type is !Send → spawn_local└─ Blocking code → spawn_blocking``` --- ## Common Errors | Error | Cause | Fix ||-------|-------|-----|| E0277 `Send` not satisfied | Non-Send in async | Use Arc or spawn_local || E0277 `Sync` not satisfied | Non-Sync shared | Wrap with Mutex || Deadlock | Lock ordering | Consistent lock order || `future is not Send` | Non-Send across await | Drop before await || `MutexGuard` across await | Guard held during suspend | Scope guard properly | --- ## Anti-Patterns | Anti-Pattern | Why Bad | Better ||--------------|---------|--------|| Arc<Mutex<T>> everywhere | Contention, complexity | Message passing || thread::sleep in async | Blocks executor | tokio::time::sleep || Holding locks across await | Blocks other tasks | Scope locks tightly || Ignoring deadlock risk | Hard to debug | Lock ordering, try_lock | --- ## Async-Specific Patterns ### Avoid MutexGuard Across Await ```rust// Bad: guard held across awaitlet guard = mutex.lock().await;do_async().await; // guard still held! // Good: scope the lock{ let guard = mutex.lock().await; // use guard} // guard droppeddo_async().await;``` ### Non-Send Types in Async ```rust// Rc is !Send, can't cross await in spawned task// Option 1: use Arc instead// Option 2: use spawn_local (single-thread runtime)// Option 3: ensure Rc is dropped before .await``` --- ## Related Skills | When | See ||------|-----|| Smart pointer choice | m02-resource || Interior mutability | m03-mutability || Performance tuning | m10-performance || Domain concurrency needs | domain-* |Coding Guidelines
The coding-guidelines skill provides developers with Rust-specific code style standards and best practices, covering naming conventions, data types, error handl
M01 Ownership
The m01-ownership skill diagnoses and resolves Rust ownership, borrowing, and lifetime errors by guiding developers to understand data ownership requirements ra
M02 Resource
m02-resource guides developers through selecting appropriate smart pointers and resource management patterns in Rust by asking design questions rather than pres