using Dpz.Core.Infrastructure;
using Dpz.Core.MessageQueue.Abstractions;
using Dpz.Core.MessageQueue.Models;
using Dpz.Core.Public.ViewModel.Messages;
using Dpz.Core.Service.ObjectStorage.Services;

namespace Dpz.Core.Web.Jobs.MessageHandlers;

/// <summary>
/// 删除图片消息处理器(单张图片)
/// 实际执行删除云存储图片的操作
/// </summary>
public class RemoveImagesHandler(
    IObjectStorageOperation objectStorageService,
    ILogger<RemoveImagesHandler> logger,
    OwnerService ownerService
) : IMessageHandler<RemoveImagesMessage>
{
    public async Task<MessageHandlerResult> HandleAsync(
        RemoveImagesMessage message,
        CancellationToken cancellationToken
    )
    {
        try
        {
            // 空 URL 视为处理成功
            if (string.IsNullOrWhiteSpace(message.ImageUrl))
            {
                logger.LogWarning("图片 URL 为空,跳过处理");
                return MessageHandlerResult.Ok();
            }

            // 不属于当前云存储的图片,视为处理成功(避免重试)
            if (!ownerService.IsOwnCdnImage(message.ImageUrl))
            {
                logger.LogInformation("图片不属于当前云存储,跳过: {ImageUrl}", message.ImageUrl);
                return MessageHandlerResult.Ok();
            }

            // 执行删除
            await objectStorageService.DeleteAsync(message.ImageUrl, cancellationToken);
            logger.LogInformation("删除图片成功: {ImageUrl}", message.ImageUrl);
            return MessageHandlerResult.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "删除图片失败: {ImageUrl}", message.ImageUrl);
            return MessageHandlerResult.Fail($"删除图片失败: {ex.Message}");
        }
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个 消息处理器(Message Handler) 类,用于处理删除云存储图片的异步消息。


类的基本信息

命名空间

Dpz.Core.Web.Jobs.MessageHandlers

属于 Web 作业的消息处理器模块。

类定义

public class RemoveImagesHandler : IMessageHandler<RemoveImagesMessage>
  • 实现了 IMessageHandler<RemoveImagesMessage> 接口
  • 专门处理 RemoveImagesMessage 类型的消息
  • 使用 主构造函数(C# 12 特性)注入依赖

依赖注入的服务

通过主构造函数注入了三个服务:

  1. IObjectStorageOperation objectStorageService
    对象存储操作服务,用于执行实际的文件删除

  2. ILogger<RemoveImagesHandler> logger
    日志记录器,用于记录处理过程和异常

  3. OwnerService ownerService
    所有权服务,用于判断图片是否属于当前云存储系统


核心方法:HandleAsync

这是消息处理的核心逻辑,包含以下步骤:

1️⃣ 空 URL 检查

if (string.IsNullOrWhiteSpace(message.ImageUrl))
{
    logger.LogWarning("图片 URL 为空,跳过处理");
    return MessageHandlerResult.Ok();
}
  • 如果图片 URL 为空或仅包含空白字符,记录警告并返回成功
  • 设计理由:空 URL 无法处理,但也不应该重试,因此标记为成功

2️⃣ 所有权验证

if (!ownerService.IsOwnCdnImage(message.ImageUrl))
{
    logger.LogInformation("图片不属于当前云存储,跳过: {ImageUrl}", message.ImageUrl);
    return MessageHandlerResult.Ok();
}
  • 检查图片是否属于当前系统的 CDN
  • 设计理由:避免删除其他系统的图片,非本系统图片也返回成功以防止无意义的重试

3️⃣ 执行删除操作

await objectStorageService.DeleteAsync(message.ImageUrl, cancellationToken);
logger.LogInformation("删除图片成功: {ImageUrl}", message.ImageUrl);
return MessageHandlerResult.Ok();
  • 调用对象存储服务的删除方法
  • 支持取消令牌,可以优雅地取消操作
  • 成功后记录信息日志

4️⃣ 异常处理

catch (Exception ex)
{
    logger.LogError(ex, "删除图片失败: {ImageUrl}", message.ImageUrl);
    return MessageHandlerResult.Fail($"删除图片失败: {ex.Message}");
}
  • 捕获所有异常并记录详细错误日志
  • 返回失败结果,通常会触发消息队列的重试机制

设计特点

幂等性设计

  • 空 URL 和非本系统图片都返回成功,避免无限重试
  • 删除操作本身具有幂等性(重复删除不存在的文件通常不会报错)

防御性编程

  • 多重验证确保不会误删除
  • 详细的日志记录便于排查问题

异步支持

  • 使用 async/await 模式
  • 支持 CancellationToken 用于优雅取消

消息队列模式

  • 通过返回 MessageHandlerResult 告知消息队列处理结果
  • 失败时可触发重试机制

典型使用场景

当用户删除图片或清理无效资源时:

  1. 系统发送 RemoveImagesMessage 消息到队列
  2. 此处理器异步接收并处理消息
  3. 验证图片归属后调用云存储 API 删除
  4. 根据结果决定是否需要重试

这种设计实现了删除操作的异步解耦,提高了系统的可靠性和性能。

评论加载中...