
m07-concurrency
by rustfs
๐2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting migration and coexistence with other S3-compatible platforms such as MinIO and Ceph.
SKILL.md
name: m07-concurrency description: "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, ๅนถๅ, ็บฟ็จ, ๅผๆญฅ, ๆญป้"
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:
-
What's the workload?
- CPU-bound โ threads (std::thread, rayon)
- I/O-bound โ async (tokio, async-std)
- Mixed โ hybrid approach
-
What's the sharing model?
- No sharing โ message passing (channels)
- Immutable sharing โ Arc
- Mutable sharing โ Arc<Mutex> or Arc<RwLock>
-
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> 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
// Bad: guard held across await
let guard = mutex.lock().await;
do_async().await; // guard still held!
// Good: scope the lock
{
let guard = mutex.lock().await;
// use guard
} // guard dropped
do_async().await;
Non-Send Types in Async
// 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-* |
Score
Total Score
Based on repository quality metrics
SKILL.mdใใกใคใซใๅซใพใใฆใใ
ใฉใคใปใณในใ่จญๅฎใใใฆใใ
100ๆๅญไปฅไธใฎ่ชฌๆใใใ
GitHub Stars 1000ไปฅไธ
1ใถๆไปฅๅ ใซๆดๆฐ
10ๅไปฅไธใใฉใผใฏใใใฆใใ
ใชใผใใณIssueใ50ๆชๆบ
ใใญใฐใฉใใณใฐ่จ่ชใ่จญๅฎใใใฆใใ
1ใคไปฅไธใฎใฟใฐใ่จญๅฎใใใฆใใ
Reviews
Reviews coming soon
