using IM.Commons.IntegrationEvents; using MassTransit; using MessageService.Domain.IReposities; using MessageService.Infrastructure; using Microsoft.EntityFrameworkCore; using MySqlConnector; namespace MessageService.WebApi.Application.EventHandlers { public class ConversationAddHandler : IConsumer, IConsumer, IConsumer { private readonly IConversationReposity reposity; private readonly MessageDbContext messageDb; public ConversationAddHandler(IConversationReposity reposity, MessageDbContext messageDb) { this.reposity = reposity; this.messageDb = messageDb; } public async Task Consume(ConsumeContext context) { var @event = context.Message; var existing = await reposity.FindActiveAsync(@event.UserId, @event.GroupId, Domain.Enums.ChatType.GROUP, context.CancellationToken); if (existing is not null) { return; } reposity.Create(new Domain.Entities.Conversation( userId: @event.UserId, targetId: @event.GroupId, targetAvatar: @event.GroupAvatar ?? @event.Avatar, targetName: @event.GroupName, lastReadSequenceId: null, unreadCount:0, chatType: Domain.Enums.ChatType.GROUP, lastMessage: string.Empty )); await SaveIdempotentlyAsync(context.CancellationToken); } public async Task Consume(ConsumeContext context) { var @event = context.Message; var existing = await reposity.FindActiveAsync(@event.OwnerId, @event.TargetId, Domain.Enums.ChatType.PRIVATE, context.CancellationToken); if (existing is not null) { return; } reposity.Create(new Domain.Entities.Conversation( userId: @event.OwnerId, targetId: @event.TargetId, targetAvatar: @event.TargetAvatar, targetName: @event.TargetNickName, lastReadSequenceId: null, unreadCount: 0, chatType: Domain.Enums.ChatType.PRIVATE, lastMessage: string.Empty )); await SaveIdempotentlyAsync(context.CancellationToken); } public async Task Consume(ConsumeContext context) { var conversation = await reposity.FindActiveAsync( context.Message.UserId, context.Message.GroupId, Domain.Enums.ChatType.GROUP, context.CancellationToken); if (conversation is not null) { conversation.SoftDelete(); } await messageDb.SaveChangesAsync(context.CancellationToken); } private async Task SaveIdempotentlyAsync(CancellationToken cancellationToken) { try { await messageDb.SaveChangesAsync(cancellationToken); } catch (DbUpdateException exception) when (exception.InnerException is MySqlException { Number: 1062 }) { messageDb.ChangeTracker.Clear(); } } } }