@nxgt / janus-webhooks-redis
Redis队列 @nxgt/janus-webhooks:
快递在Redis等候,在
@nxgt/redis的连接,
由应用程序的每个进程共享。重试时等待一个进程
崩溃、重启或被重新部署是由下一个发送的,并且请求被切断
一旦租约到期,Short将再次发送。
它实现了 WebhookQueue 端口,并通过
@nxgt/janus-webhooks/conformance 对着真正的Redis,停电
包含在每次CI运行中。
0. x。 一个小版本仍然可能改变表面;更新日志告诉我们该怎么做。
安装
bun add @nxgt/janus-webhooks-redis @nxgt/janus-webhooks @nxgt/janus @nxgt/redis
bun add zod # @nxgt/redis's peer, zod 4, if your application has none
bun add -d typescript # 6 or 7
每个peer都是必需的:
@nxgt/janus-webhooks,它实现其端口;@nxgt/janus,他的UserEvent它持有和谁持有StoreFailure它 投掷- a 同行,从来没有依赖,所以instanceof StoreFailure持有 在你的代码中;@nxgt/redis,>=0.3.1 <1布恩自己也和他有关系RedisClient, 这样就继续下去了 包子;typescript6或7。
这个 @nxgt/redis 地板是经过测试的,而不是声明的:包的规格和它的
运行类型检查 @nxgt/redis 0.3.1以及,在地板作业中,在每个CI上
运行。
它需要 Redis 7.0或更高版本,或Valkey - see
Redis必须配置的.
就像 @nxgt/janus,它期望 "moduleResolution": "bundler".
使用
import { webhooks } from '@nxgt/janus-webhooks';
import { createRedisWebhookQueue } from '@nxgt/janus-webhooks-redis';
import { connectRedis } from '@nxgt/redis';
const secret = process.env.CRM_WEBHOOK_SECRET; // whsec_…, from mintWebhookSecret()
if (!secret) throw new Error('CRM_WEBHOOK_SECRET is not set');
const redis = await connectRedis(process.env.REDIS_URL ?? 'redis://localhost:6379', {
enableOfflineQueue: false, // an outage fails the insert at once, not after 31 s
});
export const listener = webhooks({
endpoints: [{ id: 'crm', url: 'https://crm.example.com/hooks/janus', secrets: [secret] }],
queue: createRedisWebhookQueue(redis), // every process passes the same Redis and prefix
});
// janus({ …, events: listener })
process.on('SIGTERM', async () => {
await listener.close(); // gives nothing up: what waits is sent by the next process
process.exit(0);
});
给每个端点一个 id 当你第一次传递一个队列:它是什么队列
知道端点的值。 布线 覆盖连接,
前缀,以及Redis必须配置的内容。
API
| 出口 | 它是什么? |
|---|---|
createRedisWebhookQueue(redis, options?) | 返回一个 WebhookQueue,因为 webhooks({ queue }). redis 是什么 connectRedis 的回报。它不连接任何东西,也不创建任何东西:键是由第一次插入创建的。 |
RedisWebhookQueueOptions | { prefix? }每把钥匙的开头是什么? janus:webhooks: 默认情况下。每个共享交付的流程都要经过同一条。 |
Redis拥有什么?
每个交付的事件和端点id - 从来没有URL或秘密 ——与 每个方法一个Lua脚本, 所以没有两个索赔回应一个交付。 布线 每个钥匙都有吗? 它会停留多久。
陷阱
-
保留新事件类型,直到共享队列的每个进程都完成 升级。 交付
user.secondFactorEnabled或者user.secondFactorDisabled,由0.2.0编写,是STORE_FAILED(a reply that is not … a user event type)。声明它的X进程-和 其中之一也是user.recoveryCodesRegenerated或者user.recoveryCodeUsed, 由0.3.0编写,在0.2中。X进程,其中一个user.passwordChanged或者user.emailChanged,由0.4.0编写,在0.3。X进程,其中一个user.newDeviceSignedIn,由0.5.0编写,在0.4中。X进程,其中一个user.avatarChanged或者user.avatarRemoved,由0.6.0编写,在0.5.x版本中 过程——还有 终结点索赔失败 直到每个流程都升级。升级@nxgt/janus,@nxgt/janus-webhooks和@nxgt/janus-webhooks-redis它们的对等范围作为一个整体移动,每个端点被限制为 这个types旧的进程知道,并删除限制每一次 进程运行新版本:webhooks({ queue, endpoints: [{ id: 'crm', url, secrets: [secret], types: ['user.created', 'user.emailVerified', 'user.passwordReset', 'user.deleted'] }], });这个列表是针对0.1的。x的过程。当最老的跑0.2。X表示 第二个因素的事件,而不是恢复代码,加上这两个:
types: ['user.created', 'user.emailVerified', 'user.passwordReset', 'user.secondFactorEnabled', 'user.secondFactorDisabled', 'user.deleted'],当最老的跑0.3。X,它读取恢复代码的事件,但不读取 变化事件,加上这两个
types: ['user.created', 'user.emailVerified', 'user.passwordReset', 'user.secondFactorEnabled', 'user.secondFactorDisabled', 'user.recoveryCodesRegenerated', 'user.recoveryCodeUsed', 'user.deleted'],当最老的跑0.4。X,它读取变化事件,但不读取新事件 设备,加上这两个:
types: ['user.created', 'user.emailVerified', 'user.passwordReset', 'user.passwordChanged', 'user.emailChanged', 'user.secondFactorEnabled', 'user.secondFactorDisabled', 'user.recoveryCodesRegenerated', 'user.recoveryCodeUsed', 'user.deleted'], -
驱逐是数据丢失。 Redis是谁?
maxmemory-policy就清除键 一声不吭就把货丢了,不能再试,不能onGivingUp. 在 复述,与noeviction;一个满的则拒绝插入OOM, 哪一个janus报告JANUS_EVENT_FAILED. -
持久性使它持久。 没有RDB或AOF,重新启动 Redis丢失了每一个在里面等待的货物。启用AOF (
appendfsync everysec(在崩溃时最多损失一秒钟的插入)或RDB快照。 -
不支持Redis集群。 的键 交付及其端点,它们可能位于不同的槽中。使用一个 单个Redis,或者一个带有副本的主节点。
-
默认情况下,中断会使每个流等待31秒。 侦听器 等待插入,而Bun的客户机在重新连接时对命令进行排队。 与
enableOfflineQueue: false插入立即失败,流停止 On,事件报告为JANUS_EVENT_FAILED. -
每个应用程序一个前缀。 两个应用程序共享一个前缀共享 ,并且每个人都放弃对方的端点作为
endpointRemoved后orphanGrace.
文档
- 指南:连接队列,前缀,Redis必须配置什么,Redis持有什么以及每个方法如何保持原子性
- 故障排除:查看您看到的错误信息
- 路线图下一步是什么,以及什么是没有计划的
@nxgt/janus-webhooks排队指南:索赔,租约,孤儿,以及一个队列必须做什么
类型安全,计数
编译器拒绝了四个看似合理的错误,每个错误都带有
@ts-expect-error 在 test/types/queue.ts:
- URL而不是连接;
- Bun的客户端,而不是维系它的连接;
- 承诺
connectRedis没有等待的答案; - 一个
prefix这不是字符串。
执照
麻省理工学院