root
|
e30faf4cff
|
fix(stream): 缺 StringRedisTemplate Bean 时自动装配优雅退场,对齐 cache
stream 装配此前仅 @ConditionalOnClass,缺 StringRedisTemplate Bean 时
(如 exclude RedisAutoConfiguration)会因构造参数缺依赖而启动失败。加
@ConditionalOnBean(StringRedisTemplate) 使整类 back off,与 cache 一致;
顺带 @Configuration(proxyBeanMethods=false) 对齐风格。补 3 个装配测试。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 11:41:56 +08:00 |
|
root
|
0657126f60
|
test(cache): 补关键路径覆盖(loader 异常/double-check/泛型重载/sliding 回源/降级)
补齐 review 指出的覆盖缺口,均为既有正确行为的回归保护:loader 抛异常时锁 finally
释放 + 异常透传 + 不写缓存、抢锁后 double-check 命中跳过回源、getOrLoad 的
TypeReference 泛型重载往返、sliding 开启时回源新写入不重复续期、等待超时降级不写缓存。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 10:11:48 +08:00 |
|
root
|
24422d0ce4
|
refactor(cache): 纵深防御与风格清理(autoType/锁key/抖动上界/key校验/proxyBeanMethods)
- CacheValueCodec.decode 关闭 fastjson @type 自动类型(Feature.IgnoreAutoType):
纵深防御;经验证常规链路本已安全(指定目标类型时 @type 被忽略),此为显式锁定契约。
- 模板锁 key 改用 keyBuilder.buildLock(key),与 CacheKeyBuilder 单一来源,消除重复派生。
- applyJitter 上界改 nextLong(bound) 对齐 spec 半开区间 [ttl, ttl*(1+ratio));测试收紧为严格 <。
- CacheKeyBuilder.build 对空白 bizKey fail-fast,避免 "cache:null" 静默键碰撞。
- RedisCacheAutoConfiguration 用 @Configuration(proxyBeanMethods=false),省 CGLIB 代理开销。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 10:08:56 +08:00 |
|
root
|
6a4f5e460e
|
fix(cache): 公共 set(key,null) 改用短 null-ttl
set(key,null) 原按数据 TTL(可达 default-ttl-seconds)写入空值标记,使空标记长期
占位;改为与回源空值一致用 null-ttl-seconds(不抖动),空标记宜短。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 10:03:39 +08:00 |
|
root
|
c40f153642
|
fix(cache): exists 排除空值标记,与 get 口径一致
exists 原用 hasKey,会把持有空值标记的 key 判为"存在"(true),而 get 对同一 key
返回 null,二者口径打架。改为读值判断:空标记/缺失均返回 false,真实值返回 true。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 10:00:06 +08:00 |
|
root
|
8b90fe099e
|
fix(cache): 缺 StringRedisTemplate Bean 时自动装配优雅退场
原仅 @ConditionalOnClass(类在 classpath 恒真),StringRedisTemplate Bean 缺失
(多 ConnectionFactory 致 @ConditionalOnSingleCandidate 不满足,或 exclude
RedisAutoConfiguration)时会因构造参数缺依赖而启动失败。加
@ConditionalOnBean(StringRedisTemplate),配合既有
@AutoConfigureAfter(RedisAutoConfiguration) 在 Redis 装配后求值,缺 Bean 时整类
back off 而非报错。仅改 cache,不动 stream(接受两者风格暂不一致)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 09:58:00 +08:00 |
|
root
|
1e673cdf83
|
fix(cache): 构造期校验配置项,误配在装配阶段即 fail-fast
default/null-ttl-seconds、jitter-ratio、breakdown 的 lock-ttl-ms/wait-timeout-ms/
wait-interval-ms 原无校验,负值/越界要到运行期(写入非法 TTL、抖动放大数倍)才暴露。
在 RedisCacheEnhanceTemplate 构造器手工校验,非法即抛 IllegalArgumentException;
不引 hibernate-validator,守住零新依赖。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 09:54:55 +08:00 |
|
root
|
0facafc745
|
fix(cache): 击穿等待响应中断 + interval 兜底,消除空转与无限循环
未抢到锁的自旋等待原以 waited += waitIntervalMs 推进:waitIntervalMs<=0 时永不
前进 → 无限循环 hang;且 sleep 吞中断后不退出,被中断时以 Redis 往返为节奏空转
到超时、不响应协作式取消。改为溢出安全的 deadline 截止判断 + Math.max(1,interval)
兜底,sleep 返回中断信号、被中断即 break 降级并保留中断标志。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 09:51:42 +08:00 |
|
root
|
ba2606ea46
|
fix(cache): set/expire/getOrLoad 对 ttl<=0 fail-fast,杜绝 expire 误删 key
expire(key, ttl<=0) 经 applyJitter 透传 0/负值,Redis EXPIRE 非正值会立即删 key
并返回 1,使"续期"静默删数据且报 true;set(ttl<=0) 则下发非法过期抛
RedisSystemException。统一在 set/expire/doGetOrLoad 入口 requirePositiveTtl 校验,
非正 TTL 直接抛 IllegalArgumentException。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 09:46:55 +08:00 |
|
root
|
effa7bf38a
|
test(cache): 集成测试击穿并发(互斥锁下 loader 仅回源一次)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 05:10:35 +08:00 |
|
root
|
6c512ba3b2
|
test(cache): 集成测试显式 expire 续期与滑动过期(真实值续、空标记不续)
|
2026-06-26 05:08:25 +08:00 |
|
root
|
b5a649110e
|
test(cache): 集成测试穿透防护(空值缓存,loader 仅调用一次)
|
2026-06-26 05:06:05 +08:00 |
|
root
|
9abff913e5
|
test(cache): 集成测试 set/get/exists/delete 闭环 + Redis 探测脚手架
|
2026-06-26 05:03:19 +08:00 |
|
root
|
c4ad3670fc
|
feat(cache): 自动装配 + spring.factories 注册
|
2026-06-26 04:59:41 +08:00 |
|
root
|
037fdc4f9c
|
feat(cache): getOrLoad 三防(空值穿透 + TTL 抖动雪崩 + 互斥锁击穿 + 超时降级)
|
2026-06-26 04:55:42 +08:00 |
|
root
|
d164b89067
|
feat(cache): 模板读写基础(set/get/delete/exists/expire + TTL 抖动 + 滑动续期)
|
2026-06-26 04:51:07 +08:00 |
|
root
|
9605dca962
|
feat(cache): 配置属性 redis-cache.*(TTL/抖动/滑动/击穿锁)
|
2026-06-26 04:43:28 +08:00 |
|
root
|
ecbdfd8907
|
feat(cache): 值编解码器(fastjson 序列化 + 空值标记)
|
2026-06-26 04:41:02 +08:00 |
|
root
|
ce370afa83
|
feat(cache): 缓存常量与 key 构造器(前缀 + 环境隔离 + 锁 key 派生)
|
2026-06-26 04:38:02 +08:00 |
|
root
|
74f68c9680
|
feat: Redis Stream Spring Boot starter 首次提交
封装 Redis Streams 收发,零业务依赖。含自动装配、发送模板、监听容器、
autoclaim 崩溃恢复+死信淘汰、stream 定时裁剪、gzip 编解码、环境隔离。
本次随提交的改进:
- per-handler 重试次数:getMaxRetryTimes() 覆写生效,全局 redis-stream.max-retry 兜底
- 死信回调传入反序列化后的业务消息(saveExceptionFromFields)
- pom 升级 maven-surefire-plugin 至 2.22.2,使 JUnit 5 测试真正执行
- 集成测试连接信息改为 -D 注入(默认 localhost:6379),凭据不入代码
- lombok 改为 optional,不污染下游依赖
- 新增 README 使用文档
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-24 20:55:12 +08:00 |
|