mcpField
E
effect-ts-concurrency

effect-ts-concurrency

github.com/mrevanzak开发897 次安装40 周前更新
代码仓库

关于 effect-ts-concurrency

面向使用 Effect-TS 协调并行任务、后台 Fiber 或限速操作的开发者,介绍并发控制。内容涵盖限制并行度,以及使用信号量和 Deferred 进行协调。

主要功能

  1. 01限制并行执行数量
  2. 02基于 Fiber 的后台任务
  3. 03基于信号量的并发限制
  4. 04基于 Deferred 的信号传递

适用场景

  1. 01限制并发数以处理集合
  2. 02限制 API 或数据库请求速率
  3. 03协调后台任务
  4. 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一次性信号 / PromiseDeferred.await / Deferred.succeed
concurrencyall、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