在途票据池:把「同时压在某个 provider/模型上的请求数」关进一个计数
(designs/provider-reliability.md §5,Keelson ChatAdmission.cs / AdmittingChatClient.cs)。
permits 张票(缺省 8),键通常是 "<provider>/<model>"。chat-model/with-admission 把取票放在
DefaultChatModel 重试循环的里面,退避等待发生在票外。acquire-async 返回 CompletableFuture,排队期间不阻塞任何线程;
还票时直接把票移交给队首等待者(不经 available,防插队),移交在虚拟线程上完成,
免得把等待者的后续阶段跑在还票线程上。(def pool (admission/admission {:permits 4}))
(admission/with-permit pool "anthropic/claude" #(call-llm ...))
(admission/with-permit-async pool "anthropic/claude" #(call-llm-async ...))
在途票据池:把「同时压在某个 provider/模型上的请求数」关进一个计数
(designs/provider-reliability.md §5,Keelson `ChatAdmission.cs` / `AdmittingChatClient.cs`)。
- **按键分池**:每个键 `permits` 张票(缺省 8),键通常是 `"<provider>/<model>"`。
- **退避不占票**:票只跟「一次尝试」走——`chat-model/with-admission` 把取票放在
DefaultChatModel 重试循环的**里面**,退避等待发生在票外。
- **异步不占线程**:`acquire-async` 返回 CompletableFuture,排队期间不阻塞任何线程;
还票时直接把票**移交**给队首等待者(不经 available,防插队),移交在虚拟线程上完成,
免得把等待者的后续阶段跑在还票线程上。
- 排队不设死线(限流是分钟尺度);要放弃就取消:同步路径中断线程,异步路径 cancel future。
- **无全局单例**(design-principles §3):要共享就把同一个池显式传给多个 ChatModel。
```clojure
(def pool (admission/admission {:permits 4}))
(admission/with-permit pool "anthropic/claude" #(call-llm ...))
(admission/with-permit-async pool "anthropic/claude" #(call-llm-async ...))
```(acquire! adm key)阻塞取一张票。线程被中断 → 放弃排队(若票恰好已到手则自动归还)并抛 InterruptedException。
阻塞取一张票。线程被中断 → 放弃排队(若票恰好已到手则自动归还)并抛 InterruptedException。
(acquire-async adm key)取一张票 → CompletableFuture<ticket>。有空位立即完成,否则排队(不占线程)。
cancel 这个 future 即放弃排队(已到手的票由取消方负责 release!,见 acquire!)。
取一张票 → `CompletableFuture<ticket>`。有空位立即完成,否则排队(不占线程)。 cancel 这个 future 即放弃排队(已到手的票由取消方负责 `release!`,见 `acquire!`)。
(admission)(admission {:keys [permits]})建一个票据池。opts: {:permits n}(每个键最多 n 张票;≤0 或缺省 → 8)。
建一个票据池。opts: `{:permits n}`(每个键最多 n 张票;≤0 或缺省 → 8)。
缺省每键票数(与 Keelson ChatAdmission.DefaultPermits 同口径)。
缺省每键票数(与 Keelson `ChatAdmission.DefaultPermits` 同口径)。
(in-flight adm)(in-flight adm key)现在占着票的请求数;不给 key → 所有池加总(观测用,不做同步)。
现在占着票的请求数;不给 key → 所有池加总(观测用,不做同步)。
(release! ticket)归还一张票(幂等:重复调用不会把池吹大)。有等待者 → 移交给队首(跳过已取消的)。
归还一张票(幂等:重复调用不会把池吹大)。有等待者 → 移交给队首(跳过已取消的)。
(waiting adm)(waiting adm key)正在排队等票的请求数(不含已取消的);不给 key → 所有池加总。
正在排队等票的请求数(不含已取消的);不给 key → 所有池加总。
(with-permit adm key thunk)同步:取票 → 跑 thunk → finally 还票。
同步:取票 → 跑 thunk → finally 还票。
(with-permit-async adm key thunk)异步:取票(不占线程)→ 跑 thunk(返回链结果)→ 完成或失败时还票。返回链结果。
异步:取票(不占线程)→ 跑 thunk(返回链结果)→ 完成或失败时还票。返回链结果。
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |