namespace Dpz.Core.Service.Mediator.Features.Video.Commands;
/// <summary>
/// 已过时:请使用 AddDanmakuCountHandler 和 RabbitMQ 消息队列替代。
/// 原 MediatR 同步处理模式已迁移到异步消息队列,提供更好的性能和可靠性。
/// </summary>
[Obsolete(
"请使用 Web.Jobs 项目中的 AddDanmakuCountHandler 替代。MediatR 同步处理已迁移到 RabbitMQ 异步消息队列。",
false
)]
public class AddDanmakuCountEvent(
IRepository<global::Dpz.Core.Public.Entity.Video> repository,
IRepository<Barrage> barrageRepository,
IFusionCache fusionCache
) : IRequestHandler<AddDanmakuCountRequest>
{
/// <summary>
/// 回填视频弹幕计数并同步更新相关缓存。
/// </summary>
public async ValueTask<Unit> Handle(
AddDanmakuCountRequest request,
CancellationToken cancellationToken
)
{
var count = await barrageRepository
.SearchFor(x => x.Group == request.DanmakuGroup)
.CountAsync(cancellationToken);
var update = Builders<global::Dpz.Core.Public.Entity.Video>.Update.Set(
x => x.DanmakuCount,
count
);
await repository.UpdateAsync(x => x.Id == request.DanmakuGroup, update, cancellationToken);
var key = $"{CacheKey.VideoListKey}:{request.DanmakuGroup}";
var cacheValue = await fusionCache.TryGetAsync<VmVideo>(key, token: cancellationToken);
if (cacheValue.HasValue)
{
cacheValue.Value.DanmakuCount = count;
await fusionCache.SetAsync(
key,
cacheValue.Value,
TimeSpan.FromDays(1),
[CacheKey.VideoListKey],
token: cancellationToken
);
}
var listCache = await fusionCache.TryGetAsync<List<VmVideo>>(
CacheKey.VideoListKey,
token: cancellationToken
);
if (listCache.HasValue)
{
var video = listCache.Value.FirstOrDefault(x => x.Id == request.DanmakuGroup);
if (video != null)
{
video.DanmakuCount = count;
await fusionCache.SetAsync(
CacheKey.VideoListKey,
listCache.Value,
TimeSpan.FromDays(1),
[CacheKey.VideoListKey],
token: cancellationToken
);
}
}
return Unit.Value;
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
代码解释
这是一个基于 MediatR 模式的命令处理器类,用于处理视频弹幕计数的更新操作。
类的基本信息
类名: AddDanmakuCountEvent
命名空间: Dpz.Core.Service.Mediator.Features.Video.Commands
实现接口: IRequestHandler<AddDanmakuCountRequest>
重要标识
该类被标记为 [Obsolete],表示已过时,建议使用新的异步消息队列方案替代:
- 推荐使用
Web.Jobs项目中的AddDanmakuCountHandler - 从 MediatR 同步处理迁移到 RabbitMQ 异步消息队列
依赖注入
构造函数通过主构造函数语法注入三个依赖:
IRepository<global::Dpz.Core.Public.Entity.Video> repository // 视频数据仓储
IRepository<Barrage> barrageRepository // 弹幕数据仓储
IFusionCache fusionCache // 缓存服务
核心功能 - Handle 方法
该方法执行以下操作:
1. 统计弹幕数量
var count = await barrageRepository
.SearchFor(x => x.Group == request.DanmakuGroup)
.CountAsync(cancellationToken);
根据弹幕分组ID查询对应的弹幕总数。
2. 更新数据库
var update = Builders<global::Dpz.Core.Public.Entity.Video>.Update.Set(
x => x.DanmakuCount, count
);
await repository.UpdateAsync(x => x.Id == request.DanmakuGroup, update, cancellationToken);
使用 MongoDB 的 Update Builder 更新视频实体的弹幕计数字段。
3. 更新缓存
代码分两步更新缓存:
更新单个视频缓存:
- 检查是否存在特定视频的缓存
- 如果存在,更新其弹幕计数并重新设置缓存
更新视频列表缓存:
- 检查视频列表缓存是否存在
- 在列表中找到对应视频并更新其弹幕计数
- 重新设置整个列表缓存
设计特点
- 数据一致性: 同时更新数据库和缓存,确保数据一致性
- 缓存策略: 使用1天的缓存过期时间
- 异步处理: 全程使用异步操作,支持取消令牌
- 缓存标签: 使用
CacheKey.VideoListKey作为缓存标签便于管理
架构演进
这个类体现了系统架构的演进过程,从同步的 MediatR 处理模式迁移到异步的消息队列模式,以获得更好的性能和可靠性。
评论加载中...