关于 effect-ts-concurrency
面向使用 Effect-TS 协调并行任务、后台 Fiber 或限速操作的开发者,介绍并发控制。内容涵盖限制并行度,以及使用信号量和 Deferred 进行协调。
主要功能
- 01限制并行执行数量
- 02基于 Fiber 的后台任务
- 03基于信号量的并发限制
- 04基于 Deferred 的信号传递
适用场景
- 01限制并发数以处理集合
- 02限制 API 或数据库请求速率
- 03协调后台任务
- 04在并发操作间传递信号
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mrevanzak/ effect-ts-skills --skill effect-ts-concurrency安装后在 Claude Code 中输入/effect-ts-concurrency确认已加载。
详细介绍
Effect-TS 并发
概述
Effect-TS 提供轻量级 fiber,以实现高性能并发。核心原则是显式控制:始终限制并行度,以防资源耗尽。
适用场景
- 处理大型效果数组(例如,
Effect.all、Effect.forEach) - 限制外部 API 调用或数据库连接的速率
- 协调后台进程(fiber)之间的工作
- 在应用的不同部分之间发送完成或状态变更信号
不适用场景:
- 简单的顺序操作
- 标准的
Promise.all已足够时(不过为保持一致性,通常优先使用 Effect)
核心模式:限制并行度
无限制的并行是导致“打开的文件过多”或“连接超时”错误的最常见原因。
| 模式 | 实现 | 结果 |
|---|---|---|
| 不推荐 | Effect.all(effects) | 不受限制——大输入会导致崩溃 |
| 推荐 | Effect.all(effects, { concurrency: 10 }) | 受限——安全且可预测 |
快速参考
| 工具 | 用途 | 关键方法 |
|---|---|---|
| Fiber | 后台执行 | Effect.fork / Fiber.join |
| Semaphore | 限制并发 / 速率 | semaphore.withPermits(n) |
| Deferred | 一次性信号 / Promise | Deferred.await / Deferred.succeed |
| concurrency | all、forEach、mapEffect 的选项 | `{ concurrency: number |
实现
1. 限制并行度(至关重要)
处理集合时,始终指定并发度。
import { Effect } from 'effect';
// Process 1000 items, max 10 concurrent
const results = yield* Effect.all(
items.map(processItem),
{ concurrency: 10 }
);
2. 使用 Semaphore 限制速率
多个独立操作需要共享全局限制时,请使用 Semaphore。
import { Effect } from 'effect';
const program = Effect.gen(function* () {
const semaphore = yield* Effect.makeSemaphore(5); // Max 5 concurrent
yield* Effect.all(
requests.map((req) =>
semaphore.withPermits(1)(handleRequest(req))
),
{ concurrency: 'unbounded' } // Semaphore controls actual concurrency
);
});
3. 使用 Deferred 发送信号
使用 Deferred 等待来自另一个 fiber 的特定事件或值。
import { Deferred, Effect, Fiber } from 'effect';
const program = Effect.gen(function* () {
const signal = yield* Deferred.make<void>();
const worker = yield* Effect.fork(
Effect.gen(function* () {
yield* Deferred.await(signal); // Wait for signal
yield* doWork();
})
);
yield* setup();
yield* Deferred.succeed(signal, undefined); // Trigger worker
yield* Fiber.join(worker);
});
常见错误
- 无限制并行: 在
Effect.all中忘记设置{ concurrency: n }。 - Fiber 泄漏: fork fiber 后未 join 或中断(使用
Effect.scoped确保安全)。 - 死锁: Semaphore 或 Deferred 之间存在循环依赖。
危险信号——停止并重新开始
- 对大型数组使用
Effect.all,却未设置{ concurrency: n }。 - 在 Effect-TS 代码库中使用
Promise.all。 - 使用手动
setTimeout限制速率,而不是使用Effect.makeRateLimiter或Semaphore。
理由与现实对照表
| 借口 | 现实 |
|---|---|
| “只有 100 个项目” | 今天是 100 个,明天就是 10,000 个。现在就限制数量。 |
| “API 很快” | 网络延迟和服务器负载无法预测。 |
| “以后再添加并发限制” | 无限制并行是一颗随时会引爆的定时炸弹。 |
必读背景知识: 如需进一步了解无限制并行,请参阅 effect-ts-anti-patterns。
评论
支持 Markdown