上一篇里,认领崩溃消费者遗留的消息要靠 XCLAIM,而 XCLAIM 需要你事先知道 ID。XAUTOCLAIM 把「找出超时的消息」和「认领」合成一步,用游标翻页。这篇验证它的返回值、翻页规则、JUSTID,以及消息在流里已被删除时的处理。
游标 0-0 → 下一个游标 4-0 认领 ['1-0', '2-0', '3-0'] 已删除 [] 游标 4-0 → 下一个游标 7-0 认领 ['4-0', '5-0', '6-0'] 已删除 [] 游标 7-0 → 下一个游标 10-0 认领 ['7-0', '8-0', '9-0'] 已删除 [] 游标 10-0 → 下一个游标 0-0 认领 ['10-0'] 已删除 []
A 读了 10 条不 ack。B 用 XAUTOCLAIM s g B 500 0-0 COUNT 3 从游标 0-0 开始认领空闲 ≥ 500 ms 的消息,每次最多 3 条。返回的三项依次是:下一个游标、被认领的消息(带内容)、已被删除的 ID 列表。把返回的游标传给下一次调用,直到游标回到 0-0——4 次调用扫完 10 条。
> XPENDING s g - + 3 1) 1) "1-0" 2) "B" 3) (integer) 1 4) (integer) 2 2) 1) "2-0" 2) "B" 3) (integer) 1 4) (integer) 2 3) 1) "3-0" 2) "B" 3) (integer) 1 4) (integer) 2 > XAUTOCLAIM s g C 500 0-0 COUNT 3 1) "0-0" 2) (empty array) 3) (empty array)
认领让消息的 idle 重置(1 ms)、投递次数从 1 变成 2。所以马上再来一轮返回空——所有消息都还没空闲到 500 ms。这正是多个恢复进程并行跑 XAUTOCLAIM 时不会重复认领的原因。
> XAUTOCLAIM s g C 500 0-0 COUNT 3 JUSTID 1) "4-0" 2) 1) "1-0" 2) "2-0" 3) "3-0" 3) (empty array) > XPENDING s g - + 3 1) 1) "1-0" 2) "C" 3) (integer) 0 4) (integer) 2 2) 1) "2-0" 2) "C" 3) (integer) 0 4) (integer) 2 3) 1) "3-0" 2) "C" 3) (integer) 0 4) (integer) 2
加上 JUSTID 之后,返回值里只有 ID,没有消息内容,并且不增加投递次数(XPENDING 里 1-0 到 3-0 的次数仍是 2,和上一步相同),但所有权确实转给了 C。
> XDEL s 4-0 5-0
(integer) 2
> XAUTOCLAIM s g D 500 0-0 COUNT 10
1) "0-0"
2) 1) 1) "1-0"
2) 1) "job"
2) "j1"
2) 1) "2-0"
2) 1) "job"
2) "j2"
3) 1) "3-0"
2) 1) "job"
2) "j3"
4) 1) "6-0"
2) 1) "job"
2) "j6"
5) 1) "7-0"
2) 1) "job"
2) "j7"
6) 1) "8-0"
2) 1) "job"
2) "j8"
7) 1) "9-0"
2) 1) "job"
2) "j9"
8) 1) "10-0"
2) 1) "job"
2) "j10"
3) 1) "4-0"
2) "5-0"
> XPENDING s g
1) (integer) 8
2) "1-0"
3) "10-0"
4) 1) 1) "D"
2) "8"把 4-0、5-0 XDEL 之后,D 执行 XAUTOCLAIM:这两条从 PEL 中被移除(XPENDING 总数从 10 降到 8),并列在返回值的第三个元素里,其余 8 条正常认领。
10 条 pending,COUNT 3:4 次 XAUTOCLAIM 调用扫完(最后一次返回游标 0-0)