using Dpz.Core.Public.ViewModel.RequestEvent;

namespace Dpz.Core.Service.Event;

/// <summary>
/// 已过时:请使用 AddDanmakuCountHandler 和 RabbitMQ 消息队列替代。
/// 原 MediatR 同步处理模式已迁移到异步消息队列,提供更好的性能和可靠性。
/// </summary>
[Obsolete(
    "请使用 Web.Jobs 项目中的 AddDanmakuCountHandler 替代。MediatR 同步处理已迁移到 RabbitMQ 异步消息队列。",
    false
)]
public class AddDanmakuCountEvent(
    IRepository<Video> repository,
    IBarrageService barrageService,
    IFusionCache fusionCache
) : IRequestHandler<AddDanmakuCountRequest>
{
    public async Task Handle(AddDanmakuCountRequest request, CancellationToken cancellationToken)
    {
        var count = await barrageService.GetGroupBarrageCountAsync(request.DanmakuGroup);
        var update = Builders<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
                );
            }
        }
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这段代码定义了一个名为 AddDanmakuCountEvent 的事件处理器类,用于更新视频的弹幕数量。让我详细解释一下:

类的基本信息

类声明

public class AddDanmakuCountEvent : IRequestHandler<AddDanmakuCountRequest>
  • 实现了 IRequestHandler<AddDanmakuCountRequest> 接口,这是 MediatR 模式的一部分
  • 使用了主构造函数语法(C# 12 特性),接收三个依赖项

已过时标记

[Obsolete("请使用 Web.Jobs 项目中的 AddDanmakuCountHandler 替代。MediatR 同步处理已迁移到 RabbitMQ 异步消息队列。", false)]
  • 标记为过时,建议使用 RabbitMQ 异步消息队列替代
  • 表明架构正在从 MediatR 同步处理向异步消息队列迁移

依赖注入的服务

  1. IRepository<Video> - 视频数据仓储,用于数据库操作
  2. IBarrageService - 弹幕服务,用于获取弹幕数量
  3. IFusionCache - 缓存服务,用于缓存管理

核心处理逻辑

Handle 方法执行以下步骤:

1. 获取并更新数据库中的弹幕数量

var count = await barrageService.GetGroupBarrageCountAsync(request.DanmakuGroup);
var update = Builders<Video>.Update.Set(x => x.DanmakuCount, count);
await repository.UpdateAsync(x => x.Id == request.DanmakuGroup, update, cancellationToken);

2. 更新单个视频的缓存

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);
}

3. 更新视频列表缓存

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);
    }
}

设计特点

  1. 数据一致性:同时更新数据库和缓存,确保数据一致性
  2. 缓存策略:使用 1 天的缓存过期时间
  3. 错误处理:使用 TryGetAsync 避免缓存未命中时的异常
  4. 取消令牌:支持操作取消,提高系统响应性

架构演进

这个类代表了一个架构迁移的中间状态,从 MediatR 的同步事件处理模式迁移到基于 RabbitMQ 的异步消息队列模式,以获得更好的性能和可靠性。

评论加载中...