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
//! Concurrency cap for LLM requests.
//!
//! One thing, on purpose: a bounded number of in-flight requests, nothing
//! else. A local commit gate reviewing a handful of changed files does not need
//! server-oriented rate-limit machinery:
//!
//! - **Per-repo semaphores** are a map with one entry. One invocation, one
//! repo, one bucket.
//! - **A requests-per-minute window and a tokens-per-minute budget** are a
//! second, worse implementation of what `open-agent-sdk` 0.7.0 already
//! does: it classifies 429 as retryable and backs off, so a client-side
//! throttle duplicates the backoff without owning it.
//! - **Two-step token accounting** exists to reconcile an estimate against
//! actuals across a queue. With no token budget, nothing to reconcile, so
//! the "never hold the lock across an await" hazard disappears with it.
//! - **A circuit breaker** protects a shared service from a stampede. One
//! developer committing is not a stampede.
//!
//! If a real workload later shows `max_concurrent` is not enough, add the
//! narrowest mechanism that fixes it.
//!
//! [`tokio::sync::Semaphore::acquire`] returns `Result` because the
//! semaphore can be closed. This limiter never closes it, so the error
//! case is unreachable in practice; it is mapped to an empty guard rather
//! than propagated as an error the caller cannot act on.
use Arc;
use ;
/// A bounded concurrency limiter.
///
/// Cheap to clone (the semaphore is wrapped in an `Arc`); typically built
/// once per process and shared across the analyzer.
/// RAII guard holding one slot in the limiter.
///
/// Drop the guard to release the slot. In the (unreachable) error case
/// where the semaphore was closed, the guard holds no permit and dropping
/// it is a no-op - the limiter cannot make a phantom permit do useful
/// work, but the type stays total so callers do not have to handle a
/// second error variant.