@eddyq/queue

中文文档
0.2.0发布于 2026/11/05MITTypeScriptCommonJS零依赖构建来源已验证近 30 天下载 2899

Eddyq 的节点客户端 — 一个 Rust + Postgres 任务队列

中文使用文档
文档目录8 节
  1. 安装
  2. 快开始
  3. 移徙
  4. 重试公约
  5. 取消
  6. 管理表面
  7. 调试
  8. 许可证

@ eddyq/ 队列

节点.js客户端 埃迪克语name —— 运行的 Rust 任务队列 邮资, (中文(简体) ), 重写或两者兼有.

可以导入三个类:

  • Eddyq ——后卫. 交易顺序 耐用批次 迁移.
  • EddyqRedis — Redis后端(通过Redis函数). ~70克工作/零散吞食, { every: ms } 时间表,不迁移.
  • EddyqApp ——多后端容器. 在一个过程中(如:webhooks → Redis,支付 → Postgres)每行走一条路线。 见 examples/redis-basic/multi.mjs。 。 。 .

见 主读取器 用于后端取舍和基准数,或 @eddyq/wakeboard 为仪表板UI.

安装

pnpm add @eddyq/queue

我们建议 小时 或者说 线条 超过npm——见 npm 备注 为什么NAPI -RS + npm的边缘粗糙.

快开始

import { Eddyq, CancelError, RetryError } from "@eddyq/queue";

const q = await Eddyq.connect(process.env.DATABASE_URL);

q.work("send.email", async ({ payload, id, attempt, signal }) => {
  const res = await fetch(payload.url, { signal }); // signal flips on shutdown

  if (res.status === 429) {
    const after = Number(res.headers.get("retry-after") ?? 60) * 1000;
    throw new RetryError("rate limited", { delayMs: after });
  }
  if (!res.ok && attempt >= 3) {
    throw new CancelError("permanent 5xx; giving up");
  }

  return { bytes: (await res.text()).length };   // stored in eddyq_jobs.result
});

await q.start();

// ... your app runs ...

await q.shutdown(10_000);   // 10s grace; fires abort signals

移徙

eddyq不会自动在靴子上移动 复制的启动。 运行他们作为明确的部署步骤 在启动工人.

货包装有CLI:

DATABASE_URL=postgres://... npx eddyq migrate run
DATABASE_URL=postgres://... npx eddyq migrate list
DATABASE_URL=postgres://... npx eddyq migrate down --max-steps 1 --confirm

或从代码调用:

import { Eddyq } from '@eddyq/queue';
const q = await Eddyq.connect(process.env.DATABASE_URL);
const report = await q.migrate();
console.log("applied:", report.applied.map(m => `${m.version}:${m.name}`));
await q.close();

eddyq.start() 拒绝启动等待迁移。 绕过何时 schema 管理出局,通过 { skipMigrationCheck: true }。 。 。 .

migrate() 拥有能力并拥有 pg_advisory_lock 每个迁移线, 因此运行它两次(或一次从两个部署的主机),安全地序列化.

重试公约

丢弃行为
new CancelError("reason")永远的失败。 不重试, 不管怎样 maxAttempts。 。 。 .
new RetryError("reason", { delayMs: 60_000 })现在重试 + delayMs。覆盖默认备份.
任何其他 Error默认指数倒置,最多 maxAttempts。 。 。 .

每一次失败都持续到底 { name, message, stack, directive, retryDelayMs } 内 eddyq_jobs.errors[]。 。 。 .

取消

每个处理器都收到 call.signal - 一个 AbortSignal 当火 eddyq.shutdown() 名为. 传去:

q.work("download", async ({ payload, signal }) => {
  const res = await fetch(payload.url, { signal });
  return res.json();
});

shutdown(gracefulTimeoutMs?) 默认为 三万毫秒。 它广播中止到 所有机上操作人员,等待超时,然后强行取消 运行时间任务。 孤儿的工作由心跳扫荡器恢复 下一个幸存的工人.

管理表面

打电话它会做什么
enqueue(kind, payload, opts?)办一活. opts 覆盖 uniqueKey, (中文(简体) ), priority, (中文(简体) ), scheduledAtMs, (中文(简体) ), groupKey, (中文(简体) ), tags, (中文(简体) ), metadata, (中文(简体) ), maxAttempts。 。 。 .
cancel(jobId)取消任务 。 无法运行/ 完成 .
setGroupConcurrency(key, max)Cap 并行工作共享 groupKey。 。 。 .
setGroupRate(key, count, periodMs)每组托肯-布克特率限制.
pauseGroup / resumeGroup暂停发送一组.
setQueueConcurrency(queue, max)顶级总管贯穿所有工人流程.
pauseQueue / resumeQueue同样的, 对于一个命名的队列.
setQueueTimeout(queue, ms | null)此队列中默认每个工作超时 .
addSchedule(name, cron, kind, payload, opts?)增加一个编程表。 6个战地sec min hour dom month dow) (中文(简体) ). opts 覆盖 priority, (中文(简体) ), maxAttempts。 。 。 .
syncSchedules(declared)将 DB 调和到一个已宣布的列表 —— 提高每个条目, 删除列表中未列出的任何列表 。 同上;以代码管理时间表时的启动时间模式.
removeSchedule(name) 编号 : setScheduleEnabled(name, enabled)删除或切换时间表.
listSchedules() 编号 : listNamedQueues() 编号 : listGroups()读"管州志".
getStats() 编号 : listJobs(filter?, pagination?)面向板子的读取.
migrate() 编号 : migrateDown(n) 编号 : migrationStatus()司马相控.

调试

默认是典型工作量的大小——大多数用户应该放过. 把这些递给 start() 当您需要偏离时:

await q.start({
  sweepIntervalMs:        30_000,    // heartbeat sweeper cadence
  staleAfterMs:           60_000,    // when a running job is considered orphaned
  heartbeatIntervalMs:    15_000,    // worker → DB heartbeat (must be ≪ staleAfterMs)
  cleanupIntervalMs:     300_000,    // retention sweep cadence
  completedRetentionSecs: 24 * 3600, // delete completed older than this
  failedRetentionSecs:    7 * 86400,
  cancelledRetentionSecs: 7 * 86400, // pass -1 to keep forever
  leaderLeaseSecs:        30,        // single-leader maintenance lease
  fetchPollIntervalMs:    1_000,     // ignored unless poll-only
});

何时触摸他们:

  • 高吞吐量(百万个已完成工作/日) - 降级 completedRetentionSecs {\fn黑体\fs20\shad2\2ah82\3ah20\4ah33\fscx95\3ch592001\be1}所以清扫工作会继续进行.
  • 长期操作者(合法操作 > 60s的工作) 提高 staleAfterMs 这样扫荡者就不会找活活儿了. 还要加薪 heartbeatIntervalMs 按比例.
  • 许多复制品(50多个) 提高 sweepIntervalMs 所以你没有 敲响每个吊舱的扫描查询.

许可证

麻省理工学院

版本与发布记录

@eddyq/queue 共发布 28 个版本,首次发布于 2026/04/26;过去 12 个月发布了 28 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.2.0latest2026/11/058 天前
0.1.142026/10/3014 天前
0.1.132026/10/2915 天前
0.1.122026/10/2915 天前
0.1.112026/10/2816 天前
0.1.102026/10/2420 天前

关于 @eddyq/queue 的常见问题

@eddyq/queue 是什么?

Eddyq 的节点客户端 — 一个 Rust + Postgres 任务队列

如何安装 @eddyq/queue?

在项目目录运行 npm install @eddyq/queue,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 eddyq,可以用 npx eddyq 直接运行。

@eddyq/queue 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@eddyq/queue 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@eddyq/queue 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@eddyq/queue 可以商用吗?

@eddyq/queue 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@eddyq/queue 的下载量有多少?

根据 npm 官方下载统计,@eddyq/queue 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,899 次,日均约 97 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@eddyq/queue 还在维护吗?

最新版本 0.2.0 发布于 2026/11/05(8 天前);至今共发布 28 个版本,其中过去 12 个月发布了 28 个;首次发布于 2026/04/26。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。