-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathconcurrency.yaml
More file actions
200 lines (173 loc) · 9.06 KB
/
concurrency.yaml
File metadata and controls
200 lines (173 loc) · 9.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# Concurrency Code Review Guidelines
# Comprehensive rules for thread safety, deadlocks, race conditions, and async patterns
description: Concurrency best practices covering thread safety, deadlock prevention, race conditions, parallel processing, and async patterns
globs:
- "**/*.py"
- "**/*.java"
- "**/*.ts"
- "**/*.js"
- "**/*.go"
- "**/*.rb"
- "**/*.rs"
- "**/*.cs"
- "**/*.cpp"
- "**/*.c"
- "**/*.swift"
- "**/*.kt"
- "**/*.scala"
rules:
# Thread Safety Rules
- name: protect-shared-mutable-state
description: >
All shared mutable state must be protected by synchronization primitives.
Use mutexes, locks, or synchronized blocks. Document which lock protects which data.
Consider using thread-safe collections. Run tests with race detectors (go -race, TSAN).
severity: critical
- name: use-atomic-operations-for-simple-state
description: >
Use atomic operations for simple shared state like counters and flags.
Atomics are faster than locks for single-variable operations. Use AtomicInteger,
atomic.Int64, std::atomic, etc. Be aware that atomics don't provide compound atomicity.
severity: medium
- name: prefer-immutability
description: >
Prefer immutable data structures in concurrent code. Immutable objects are inherently
thread-safe and eliminate many concurrency bugs. Use defensive copying when sharing
mutable objects. Consider persistent data structures for efficient immutable updates.
severity: medium
- name: minimize-lock-scope
description: >
Keep critical sections as small as possible. Hold locks only for the minimum time
necessary. Don't perform I/O, blocking calls, or long computations while holding locks.
Extract non-critical code outside synchronized blocks. Profile lock contention.
severity: high
- name: use-read-write-locks-appropriately
description: >
Use read-write locks (RWMutex, ReadWriteLock) when reads significantly outnumber writes.
Multiple readers can proceed concurrently while writes require exclusive access.
Be aware of writer starvation in read-heavy workloads. Profile to verify benefit.
severity: medium
# Deadlock Prevention Rules
- name: acquire-locks-in-consistent-order
description: >
Always acquire multiple locks in a consistent, documented order to prevent deadlocks.
Define a global lock ordering based on lock hierarchy or identity. Use lock leveling.
Document lock ordering requirements. Consider using lock-free algorithms where possible.
severity: critical
- name: use-lock-timeouts
description: >
Use timeouts when acquiring locks to prevent indefinite blocking and detect deadlocks.
tryLock with timeout allows recovery from potential deadlock situations. Log timeout
events for debugging. Implement proper retry or fallback logic on timeout.
severity: high
- name: avoid-nested-locks
description: >
Minimize nested lock acquisition as it increases deadlock risk. Restructure code
to acquire locks sequentially rather than nested. If unavoidable, strictly follow
lock ordering. Consider using a single coarser-grained lock instead.
severity: high
- name: implement-deadlock-detection
description: >
In complex systems, implement deadlock detection mechanisms. Use timeout-based
detection, resource allocation graphs, or lock dependency tracking. Log lock
acquisition patterns for debugging. Consider using tools like TSAN or lock checkers.
severity: medium
# Race Condition Prevention Rules
- name: protect-critical-sections
description: >
Identify and protect all critical sections where shared state is accessed.
A critical section must be atomic from the perspective of other threads.
Use appropriate synchronization: mutexes, semaphores, or lock-free structures.
severity: critical
- name: avoid-check-then-act-races
description: >
Check-then-act patterns (if condition then act) are inherently racy without synchronization.
Condition may change between check and act. Use atomic compare-and-swap operations,
or hold lock during entire check-then-act sequence. Examples: lazy initialization, file exists check.
severity: high
- name: use-thread-safe-collections
description: >
Use thread-safe collection implementations for shared data structures. Standard collections
are not thread-safe. Use ConcurrentHashMap, CopyOnWriteArrayList, sync.Map, etc.
Understand their consistency guarantees. Compound operations may still need synchronization.
severity: high
# Parallel Processing Rules
- name: choose-appropriate-task-granularity
description: >
Balance task granularity for parallel processing. Too fine-grained creates overhead from
task management. Too coarse-grained limits parallelism and causes load imbalance.
Profile to find optimal granularity. Consider data locality and cache effects.
severity: medium
- name: implement-work-stealing
description: >
Use work-stealing schedulers for dynamic load balancing. Idle workers steal tasks from
busy workers' queues. Better than static partitioning for uneven workloads. Available
in ForkJoinPool (Java), Task Parallel Library (.NET), Rayon (Rust), etc.
severity: medium
- name: balance-load-across-workers
description: >
Distribute work evenly across parallel workers. Avoid scenarios where one worker has
much more work than others. Use dynamic work distribution for unpredictable workloads.
Monitor worker utilization. Consider data-dependent execution time variations.
severity: medium
- name: limit-parallel-degree
description: >
Limit parallelism degree based on available resources. More threads than cores causes
context switching overhead. Consider I/O-bound vs CPU-bound characteristics. Use
thread pools with bounded size. Monitor and tune based on performance metrics.
severity: medium
# Async Patterns Rules
- name: use-non-blocking-io
description: >
Use non-blocking I/O for concurrent connections to avoid thread-per-connection overhead.
async/await, epoll, kqueue, IOCP enable handling many connections with few threads.
Essential for high-concurrency servers. Be aware of head-of-line blocking in HTTP/2.
severity: high
- name: understand-event-loop-blocking
description: >
Never block the event loop in single-threaded async runtimes (Node.js, asyncio).
Long CPU tasks freeze all concurrent operations. Offload CPU work to worker threads
or processes. Use setImmediate/nextTick to yield. Profile for event loop delays.
severity: critical
- name: implement-backpressure
description: >
Implement backpressure to handle producer-consumer rate mismatch. Without backpressure,
fast producers overwhelm slow consumers, causing memory exhaustion. Use bounded queues,
reactive streams, or flow control protocols. Signal upstream to slow down.
severity: high
- name: handle-async-cancellation
description: >
Implement proper cancellation for async operations. Use CancellationToken, AbortController,
or context cancellation. Check cancellation state at appropriate points. Clean up
resources on cancellation. Propagate cancellation through async call chains.
severity: medium
- name: avoid-async-void
description: >
Avoid async void methods (except event handlers) as exceptions can't be caught by callers.
Always return Task/Promise/Future from async methods. Async void causes unobserved
exceptions and makes testing difficult. Use async Task for fire-and-forget with proper error handling.
severity: high
- name: handle-concurrent-access-to-async-state
description: >
Async code can have race conditions even in single-threaded environments. State may
change during await points. Don't assume state is stable across await. Use async-aware
synchronization primitives. Be careful with instance state in async methods.
severity: high
- name: use-structured-concurrency
description: >
Use structured concurrency patterns to manage async task lifecycles. Parent tasks wait
for all child tasks. Cancellation propagates to children. Errors are properly collected.
Prevents orphaned tasks and resource leaks. Use TaskGroup, asyncio.gather, or similar.
severity: medium
- name: avoid-shared-state-in-async
description: >
Minimize shared mutable state in async code. Pass data through return values and
parameters instead. If sharing is necessary, use async-safe synchronization. Consider
actor models for state encapsulation. Document any shared state clearly.
severity: medium
- name: test-concurrent-code-thoroughly
description: >
Concurrent bugs are non-deterministic and hard to reproduce. Use stress testing, fuzzing,
and systematic testing tools. Run tests with race detectors enabled. Test with different
thread counts and timing. Use model checkers for critical sections.
severity: high