From 3de787e07c9e0f5e4880d2e21fbaa274fdbb671f Mon Sep 17 00:00:00 2001 From: Andrija Stevanovic Date: Sat, 7 Mar 2026 16:15:21 +0100 Subject: [PATCH 1/3] implement feedback loop --- .../Abstract/MessageBroking/IMessage.cs | 5 +++- .../Message/AddArrow/AddArrowMessage.cs | 8 ++++- .../Common/Message/AddLine/AddLineMessage.cs | 8 ++++- .../AddRectangle/AddRectangleMessage.cs | 8 ++++- .../AddTextShape/AddTextShapeMessage.cs | 8 ++++- .../Message/ErrorMessage/ErrorMessage.cs | 12 ++++++++ .../ErrorMessage/ErrorMessageHandler.cs | 18 ++++++++++++ .../IErrorMessageHandleStrategy.cs | 6 ++++ .../Message/MoveShape/MoveShapeMessage.cs | 8 ++++- .../Common/Message/TestMessage/TestMessage.cs | 8 ++++- dotnet/AipsRT/Hubs/WhiteboardHub.cs | 2 +- .../Model/Whiteboard/WhiteboardManager.cs | 12 ++++++++ dotnet/AipsRT/Program.cs | 5 ++++ .../ErrorSubscriberBackgroundService.cs | 25 ++++++++++++++++ .../Services/Interfaces/IMessagingService.cs | 2 +- dotnet/AipsRT/Services/MessagingService.cs | 4 +-- .../AipsRT/Services/RtErrorHandleStrategy.cs | 29 +++++++++++++++++++ dotnet/AipsWorker/WorkerService.cs | 14 ++++++++- 18 files changed, 170 insertions(+), 12 deletions(-) create mode 100644 dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessage.cs create mode 100644 dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessageHandler.cs create mode 100644 dotnet/AipsCore/Application/Common/Message/ErrorMessage/IErrorMessageHandleStrategy.cs create mode 100644 dotnet/AipsRT/Services/ErrorSubscriberBackgroundService.cs create mode 100644 dotnet/AipsRT/Services/RtErrorHandleStrategy.cs diff --git a/dotnet/AipsCore/Application/Abstract/MessageBroking/IMessage.cs b/dotnet/AipsCore/Application/Abstract/MessageBroking/IMessage.cs index ecade00..fcc7fc5 100644 --- a/dotnet/AipsCore/Application/Abstract/MessageBroking/IMessage.cs +++ b/dotnet/AipsCore/Application/Abstract/MessageBroking/IMessage.cs @@ -1,3 +1,6 @@ namespace AipsCore.Application.Abstract.MessageBroking; -public interface IMessage; \ No newline at end of file +public interface IMessage +{ + Guid? GetWhiteboardId(); +}; \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/AddArrow/AddArrowMessage.cs b/dotnet/AipsCore/Application/Common/Message/AddArrow/AddArrowMessage.cs index ee857f3..3294a15 100644 --- a/dotnet/AipsCore/Application/Common/Message/AddArrow/AddArrowMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/AddArrow/AddArrowMessage.cs @@ -3,4 +3,10 @@ using AipsCore.Application.Models.Shape.Command.CreateArrow; namespace AipsCore.Application.Common.Message.AddArrow; -public record AddArrowMessage(CreateArrowCommand Command) : IMessage; \ No newline at end of file +public record AddArrowMessage(CreateArrowCommand Command) : IMessage +{ + public Guid? GetWhiteboardId() + { + return Guid.Parse(Command.WhiteboardId); + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/AddLine/AddLineMessage.cs b/dotnet/AipsCore/Application/Common/Message/AddLine/AddLineMessage.cs index e7769b5..36428ef 100644 --- a/dotnet/AipsCore/Application/Common/Message/AddLine/AddLineMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/AddLine/AddLineMessage.cs @@ -3,4 +3,10 @@ using AipsCore.Application.Models.Shape.Command.CreateLine; namespace AipsCore.Application.Common.Message.AddLine; -public record AddLineMessage(CreateLineCommand Command) : IMessage; \ No newline at end of file +public record AddLineMessage(CreateLineCommand Command) : IMessage +{ + public Guid? GetWhiteboardId() + { + return Guid.Parse(Command.WhiteboardId); + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/AddRectangle/AddRectangleMessage.cs b/dotnet/AipsCore/Application/Common/Message/AddRectangle/AddRectangleMessage.cs index 0277ee1..75b1410 100644 --- a/dotnet/AipsCore/Application/Common/Message/AddRectangle/AddRectangleMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/AddRectangle/AddRectangleMessage.cs @@ -3,4 +3,10 @@ using AipsCore.Application.Models.Shape.Command.CreateRectangle; namespace AipsCore.Application.Common.Message.AddRectangle; -public record AddRectangleMessage(CreateRectangleCommand Command) : IMessage; \ No newline at end of file +public record AddRectangleMessage(CreateRectangleCommand Command) : IMessage +{ + public Guid? GetWhiteboardId() + { + return Guid.Parse(Command.WhiteboardId); + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/AddTextShape/AddTextShapeMessage.cs b/dotnet/AipsCore/Application/Common/Message/AddTextShape/AddTextShapeMessage.cs index d65a896..c6a6127 100644 --- a/dotnet/AipsCore/Application/Common/Message/AddTextShape/AddTextShapeMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/AddTextShape/AddTextShapeMessage.cs @@ -3,4 +3,10 @@ using AipsCore.Application.Models.Shape.Command.CreateTextShape; namespace AipsCore.Application.Common.Message.AddTextShape; -public record AddTextShapeMessage(CreateTextShapeCommand Command) : IMessage; \ No newline at end of file +public record AddTextShapeMessage(CreateTextShapeCommand Command) : IMessage +{ + public Guid? GetWhiteboardId() + { + return Guid.Parse(Command.WhiteboardId); + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessage.cs b/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessage.cs new file mode 100644 index 0000000..ae77633 --- /dev/null +++ b/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessage.cs @@ -0,0 +1,12 @@ +using AipsCore.Application.Abstract.MessageBroking; +using AipsCore.Domain.Common.Validation; + +namespace AipsCore.Application.Common.Message.ErrorMessage; + +public record ErrorMessage(Guid WhiteboardId, ICollection Errors) : IMessage +{ + public Guid? GetWhiteboardId() + { + return WhiteboardId; + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessageHandler.cs b/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessageHandler.cs new file mode 100644 index 0000000..d1e2152 --- /dev/null +++ b/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessageHandler.cs @@ -0,0 +1,18 @@ +using AipsCore.Application.Abstract.MessageBroking; + +namespace AipsCore.Application.Common.Message.ErrorMessage; + +public class ErrorMessageHandler : IMessageHandler +{ + private readonly IErrorMessageHandleStrategy _handleStrategy; + + public ErrorMessageHandler(IErrorMessageHandleStrategy handleStrategy) + { + _handleStrategy = handleStrategy; + } + + public async Task Handle(ErrorMessage message, CancellationToken cancellationToken) + { + await _handleStrategy.Handle(message, cancellationToken); + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/ErrorMessage/IErrorMessageHandleStrategy.cs b/dotnet/AipsCore/Application/Common/Message/ErrorMessage/IErrorMessageHandleStrategy.cs new file mode 100644 index 0000000..027710c --- /dev/null +++ b/dotnet/AipsCore/Application/Common/Message/ErrorMessage/IErrorMessageHandleStrategy.cs @@ -0,0 +1,6 @@ +namespace AipsCore.Application.Common.Message.ErrorMessage; + +public interface IErrorMessageHandleStrategy +{ + Task Handle(ErrorMessage message, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/MoveShape/MoveShapeMessage.cs b/dotnet/AipsCore/Application/Common/Message/MoveShape/MoveShapeMessage.cs index eb97ad7..bf3a8d9 100644 --- a/dotnet/AipsCore/Application/Common/Message/MoveShape/MoveShapeMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/MoveShape/MoveShapeMessage.cs @@ -3,4 +3,10 @@ using AipsCore.Application.Models.Shape.Command.MoveShape; namespace AipsCore.Application.Common.Message.MoveShape; -public record MoveShapeMessage(MoveShapeCommand Command) : IMessage; \ No newline at end of file +public record MoveShapeMessage(Guid WhiteboardId, MoveShapeCommand Command) : IMessage +{ + public Guid? GetWhiteboardId() + { + return WhiteboardId; + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/TestMessage/TestMessage.cs b/dotnet/AipsCore/Application/Common/Message/TestMessage/TestMessage.cs index e6559e6..710c40a 100644 --- a/dotnet/AipsCore/Application/Common/Message/TestMessage/TestMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/TestMessage/TestMessage.cs @@ -2,4 +2,10 @@ using AipsCore.Application.Abstract.MessageBroking; namespace AipsCore.Application.Common.Message.TestMessage; -public record TestMessage(string Text) : IMessage; \ No newline at end of file +public record TestMessage(string Text) : IMessage +{ + public Guid? GetWhiteboardId() + { + return null; + } +} \ No newline at end of file diff --git a/dotnet/AipsRT/Hubs/WhiteboardHub.cs b/dotnet/AipsRT/Hubs/WhiteboardHub.cs index ec22db5..9ff64f8 100644 --- a/dotnet/AipsRT/Hubs/WhiteboardHub.cs +++ b/dotnet/AipsRT/Hubs/WhiteboardHub.cs @@ -127,6 +127,6 @@ public class WhiteboardHub : Hub { await MoveShape(moveShape); - await _messagingService.MoveShape(moveShape); + await _messagingService.MoveShape(CurrentWhiteboard.WhiteboardId, moveShape); } } \ No newline at end of file diff --git a/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs b/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs index 10c19dc..fcdcac6 100644 --- a/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs +++ b/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs @@ -32,6 +32,18 @@ public class WhiteboardManager _whiteboards.TryRemove(whiteboardId, out _); } + public async Task RefreshWhiteboard(Guid whiteboardId) + { + var whiteboard = GetWhiteboard(whiteboardId); + + if (whiteboard == null) + { + RemoveWhiteboard(whiteboardId); + } + + await AddWhiteboard(whiteboardId); + } + public Whiteboard? GetWhiteboard(Guid whiteboardId) { return _whiteboards.GetValueOrDefault(whiteboardId); diff --git a/dotnet/AipsRT/Program.cs b/dotnet/AipsRT/Program.cs index 0995a0a..97c3f0b 100644 --- a/dotnet/AipsRT/Program.cs +++ b/dotnet/AipsRT/Program.cs @@ -1,3 +1,4 @@ +using AipsCore.Application.Common.Message.ErrorMessage; using AipsCore.Infrastructure.DI; using AipsRT.Hubs; using AipsRT.Model.Whiteboard; @@ -15,6 +16,10 @@ builder.Configuration.AddEnvironmentVariables(); builder.Services.AddSignalR(); builder.Services.AddAips(builder.Configuration); +builder.Services.AddAipsMessageHandlers(); + +builder.Services.AddSingleton(); +builder.Services.AddHostedService(); builder.Services.AddScoped(); builder.Services.AddSingleton(); diff --git a/dotnet/AipsRT/Services/ErrorSubscriberBackgroundService.cs b/dotnet/AipsRT/Services/ErrorSubscriberBackgroundService.cs new file mode 100644 index 0000000..36146df --- /dev/null +++ b/dotnet/AipsRT/Services/ErrorSubscriberBackgroundService.cs @@ -0,0 +1,25 @@ +using AipsCore.Application.Abstract; +using AipsCore.Application.Abstract.MessageBroking; +using AipsCore.Application.Common.Message.ErrorMessage; + +namespace AipsRT.Services; + +public class ErrorSubscriberBackgroundService : BackgroundService +{ + private readonly IMessageSubscriber _subscriber; + private readonly IDispatcher _dispatcher; + + public ErrorSubscriberBackgroundService(IMessageSubscriber subscriber, IDispatcher dispatcher) + { + _subscriber = subscriber; + _dispatcher = dispatcher; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + await _subscriber.SubscribeAsync(async (errorMessage, ct) => + { + await _dispatcher.Execute(errorMessage, ct); + }); + } +} \ No newline at end of file diff --git a/dotnet/AipsRT/Services/Interfaces/IMessagingService.cs b/dotnet/AipsRT/Services/Interfaces/IMessagingService.cs index 3bbf790..97838e0 100644 --- a/dotnet/AipsRT/Services/Interfaces/IMessagingService.cs +++ b/dotnet/AipsRT/Services/Interfaces/IMessagingService.cs @@ -11,5 +11,5 @@ public interface IMessagingService Task CreateLine(Guid whiteboardId, Line line); Task CreateTextShape(Guid whiteboardId, TextShape textShape); - Task MoveShape(MoveShapeCommand moveShape); + Task MoveShape(Guid whiteboardId, MoveShapeCommand moveShape); } \ No newline at end of file diff --git a/dotnet/AipsRT/Services/MessagingService.cs b/dotnet/AipsRT/Services/MessagingService.cs index 3ad2aa6..3f139bd 100644 --- a/dotnet/AipsRT/Services/MessagingService.cs +++ b/dotnet/AipsRT/Services/MessagingService.cs @@ -95,9 +95,9 @@ public class MessagingService : IMessagingService await _messagePublisher.PublishAsync(message); } - public async Task MoveShape(MoveShapeCommand moveShape) + public async Task MoveShape(Guid whiteboardId, MoveShapeCommand moveShape) { - var message = new MoveShapeMessage(moveShape); + var message = new MoveShapeMessage(whiteboardId, moveShape); await _messagePublisher.PublishAsync(message); } } \ No newline at end of file diff --git a/dotnet/AipsRT/Services/RtErrorHandleStrategy.cs b/dotnet/AipsRT/Services/RtErrorHandleStrategy.cs new file mode 100644 index 0000000..7ce8646 --- /dev/null +++ b/dotnet/AipsRT/Services/RtErrorHandleStrategy.cs @@ -0,0 +1,29 @@ +using AipsCore.Application.Common.Message.ErrorMessage; +using AipsRT.Hubs; +using AipsRT.Model.Whiteboard; +using Microsoft.AspNetCore.SignalR; + +namespace AipsRT.Services; + +public class RtErrorHandleStrategy : IErrorMessageHandleStrategy +{ + private readonly IHubContext _hubContext; + private readonly WhiteboardManager _whiteboardManager; + + public RtErrorHandleStrategy(IHubContext hubContext, WhiteboardManager whiteboardManager) + { + _hubContext = hubContext; + _whiteboardManager = whiteboardManager; + } + + public async Task Handle(ErrorMessage message, CancellationToken cancellationToken) + { + await _whiteboardManager.RefreshWhiteboard(message.WhiteboardId); + + var whiteboard = _whiteboardManager.GetWhiteboard(message.WhiteboardId)!; + + await _hubContext.Clients + .Group(whiteboard.WhiteboardId.ToString()) + .SendAsync("InitWhiteboard", whiteboard, cancellationToken); + } +} \ No newline at end of file diff --git a/dotnet/AipsWorker/WorkerService.cs b/dotnet/AipsWorker/WorkerService.cs index 5f6d8a8..c1c9b4a 100644 --- a/dotnet/AipsWorker/WorkerService.cs +++ b/dotnet/AipsWorker/WorkerService.cs @@ -1,6 +1,7 @@ using System.Reflection; using AipsCore.Application.Abstract; using AipsCore.Application.Abstract.MessageBroking; +using AipsCore.Application.Common.Message.ErrorMessage; using AipsCore.Application.Common.Message.TestMessage; using AipsCore.Domain.Common.Validation; using AipsWorker.Utilities; @@ -12,12 +13,14 @@ public class WorkerService : BackgroundService { private readonly IDispatcher _dispatcher; private readonly IMessageTypesProvider _messageTypesProvider; + private readonly IMessagePublisher _publisher; private readonly SubscribeMethodUtility _subscribeMethodUtility; - public WorkerService(IMessageSubscriber subscriber, IDispatcher dispatcher, IMessageTypesProvider messageTypesProvider) + public WorkerService(IMessageSubscriber subscriber, IDispatcher dispatcher, IMessageTypesProvider messageTypesProvider, IMessagePublisher publisher) { _dispatcher = dispatcher; _messageTypesProvider = messageTypesProvider; + _publisher = publisher; _subscribeMethodUtility = new SubscribeMethodUtility(subscriber); } @@ -45,6 +48,15 @@ public class WorkerService : BackgroundService } catch (ValidationException validationException) { + var whiteboardId = message.GetWhiteboardId(); + + if (whiteboardId is not null) + { + var errorMessage = new ErrorMessage(whiteboardId.Value, validationException.ValidationErrors); + + await _publisher.PublishAsync(errorMessage, ct); + } + Console.WriteLine("===Validation Exception: "); foreach (var error in validationException.ValidationErrors) { From 0e6caa136e0cd8ac337d751ecf410db251360188 Mon Sep 17 00:00:00 2001 From: Andrija Stevanovic Date: Sat, 7 Mar 2026 17:51:02 +0100 Subject: [PATCH 2/3] cleaned code --- .../Abstract/IWhiteboardAwareContext.cs | 6 ++++++ .../Abstract/MessageBroking/IMessage.cs | 5 +---- .../Common/Message/AddArrow/AddArrowMessage.cs | 5 +++-- .../Common/Message/AddLine/AddLineMessage.cs | 5 +++-- .../Message/AddRectangle/AddRectangleMessage.cs | 5 +++-- .../Message/AddTextShape/AddTextShapeMessage.cs | 5 +++-- .../Common/Message/ErrorMessage/ErrorMessage.cs | 5 +++-- .../Common/Message/MoveShape/MoveShapeMessage.cs | 5 +++-- .../Common/Message/TestMessage/TestMessage.cs | 8 +------- dotnet/AipsRT/Hubs/WhiteboardHub.cs | 2 +- .../AipsRT/Model/Whiteboard/WhiteboardManager.cs | 6 +++--- dotnet/AipsWorker/WorkerService.cs | 14 ++++++++------ front/src/stores/whiteboard.ts | 1 + 13 files changed, 39 insertions(+), 33 deletions(-) create mode 100644 dotnet/AipsCore/Application/Abstract/IWhiteboardAwareContext.cs diff --git a/dotnet/AipsCore/Application/Abstract/IWhiteboardAwareContext.cs b/dotnet/AipsCore/Application/Abstract/IWhiteboardAwareContext.cs new file mode 100644 index 0000000..a391986 --- /dev/null +++ b/dotnet/AipsCore/Application/Abstract/IWhiteboardAwareContext.cs @@ -0,0 +1,6 @@ +namespace AipsCore.Application.Abstract; + +public interface IWhiteboardAwareContext +{ + Guid GetWhiteboardId(); +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Abstract/MessageBroking/IMessage.cs b/dotnet/AipsCore/Application/Abstract/MessageBroking/IMessage.cs index fcc7fc5..ecade00 100644 --- a/dotnet/AipsCore/Application/Abstract/MessageBroking/IMessage.cs +++ b/dotnet/AipsCore/Application/Abstract/MessageBroking/IMessage.cs @@ -1,6 +1,3 @@ namespace AipsCore.Application.Abstract.MessageBroking; -public interface IMessage -{ - Guid? GetWhiteboardId(); -}; \ No newline at end of file +public interface IMessage; \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Common/Message/AddArrow/AddArrowMessage.cs b/dotnet/AipsCore/Application/Common/Message/AddArrow/AddArrowMessage.cs index 3294a15..e9920b7 100644 --- a/dotnet/AipsCore/Application/Common/Message/AddArrow/AddArrowMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/AddArrow/AddArrowMessage.cs @@ -1,11 +1,12 @@ +using AipsCore.Application.Abstract; using AipsCore.Application.Abstract.MessageBroking; using AipsCore.Application.Models.Shape.Command.CreateArrow; namespace AipsCore.Application.Common.Message.AddArrow; -public record AddArrowMessage(CreateArrowCommand Command) : IMessage +public record AddArrowMessage(CreateArrowCommand Command) : IMessage, IWhiteboardAwareContext { - public Guid? GetWhiteboardId() + public Guid GetWhiteboardId() { return Guid.Parse(Command.WhiteboardId); } diff --git a/dotnet/AipsCore/Application/Common/Message/AddLine/AddLineMessage.cs b/dotnet/AipsCore/Application/Common/Message/AddLine/AddLineMessage.cs index 36428ef..19060c8 100644 --- a/dotnet/AipsCore/Application/Common/Message/AddLine/AddLineMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/AddLine/AddLineMessage.cs @@ -1,11 +1,12 @@ +using AipsCore.Application.Abstract; using AipsCore.Application.Abstract.MessageBroking; using AipsCore.Application.Models.Shape.Command.CreateLine; namespace AipsCore.Application.Common.Message.AddLine; -public record AddLineMessage(CreateLineCommand Command) : IMessage +public record AddLineMessage(CreateLineCommand Command) : IMessage, IWhiteboardAwareContext { - public Guid? GetWhiteboardId() + public Guid GetWhiteboardId() { return Guid.Parse(Command.WhiteboardId); } diff --git a/dotnet/AipsCore/Application/Common/Message/AddRectangle/AddRectangleMessage.cs b/dotnet/AipsCore/Application/Common/Message/AddRectangle/AddRectangleMessage.cs index 75b1410..a406708 100644 --- a/dotnet/AipsCore/Application/Common/Message/AddRectangle/AddRectangleMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/AddRectangle/AddRectangleMessage.cs @@ -1,11 +1,12 @@ +using AipsCore.Application.Abstract; using AipsCore.Application.Abstract.MessageBroking; using AipsCore.Application.Models.Shape.Command.CreateRectangle; namespace AipsCore.Application.Common.Message.AddRectangle; -public record AddRectangleMessage(CreateRectangleCommand Command) : IMessage +public record AddRectangleMessage(CreateRectangleCommand Command) : IMessage, IWhiteboardAwareContext { - public Guid? GetWhiteboardId() + public Guid GetWhiteboardId() { return Guid.Parse(Command.WhiteboardId); } diff --git a/dotnet/AipsCore/Application/Common/Message/AddTextShape/AddTextShapeMessage.cs b/dotnet/AipsCore/Application/Common/Message/AddTextShape/AddTextShapeMessage.cs index c6a6127..3366057 100644 --- a/dotnet/AipsCore/Application/Common/Message/AddTextShape/AddTextShapeMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/AddTextShape/AddTextShapeMessage.cs @@ -1,11 +1,12 @@ +using AipsCore.Application.Abstract; using AipsCore.Application.Abstract.MessageBroking; using AipsCore.Application.Models.Shape.Command.CreateTextShape; namespace AipsCore.Application.Common.Message.AddTextShape; -public record AddTextShapeMessage(CreateTextShapeCommand Command) : IMessage +public record AddTextShapeMessage(CreateTextShapeCommand Command) : IMessage, IWhiteboardAwareContext { - public Guid? GetWhiteboardId() + public Guid GetWhiteboardId() { return Guid.Parse(Command.WhiteboardId); } diff --git a/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessage.cs b/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessage.cs index ae77633..18e411e 100644 --- a/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/ErrorMessage/ErrorMessage.cs @@ -1,11 +1,12 @@ +using AipsCore.Application.Abstract; using AipsCore.Application.Abstract.MessageBroking; using AipsCore.Domain.Common.Validation; namespace AipsCore.Application.Common.Message.ErrorMessage; -public record ErrorMessage(Guid WhiteboardId, ICollection Errors) : IMessage +public record ErrorMessage(Guid WhiteboardId, ICollection Errors) : IMessage, IWhiteboardAwareContext { - public Guid? GetWhiteboardId() + public Guid GetWhiteboardId() { return WhiteboardId; } diff --git a/dotnet/AipsCore/Application/Common/Message/MoveShape/MoveShapeMessage.cs b/dotnet/AipsCore/Application/Common/Message/MoveShape/MoveShapeMessage.cs index bf3a8d9..8eb27b7 100644 --- a/dotnet/AipsCore/Application/Common/Message/MoveShape/MoveShapeMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/MoveShape/MoveShapeMessage.cs @@ -1,11 +1,12 @@ +using AipsCore.Application.Abstract; using AipsCore.Application.Abstract.MessageBroking; using AipsCore.Application.Models.Shape.Command.MoveShape; namespace AipsCore.Application.Common.Message.MoveShape; -public record MoveShapeMessage(Guid WhiteboardId, MoveShapeCommand Command) : IMessage +public record MoveShapeMessage(Guid WhiteboardId, MoveShapeCommand Command) : IMessage, IWhiteboardAwareContext { - public Guid? GetWhiteboardId() + public Guid GetWhiteboardId() { return WhiteboardId; } diff --git a/dotnet/AipsCore/Application/Common/Message/TestMessage/TestMessage.cs b/dotnet/AipsCore/Application/Common/Message/TestMessage/TestMessage.cs index 710c40a..e6559e6 100644 --- a/dotnet/AipsCore/Application/Common/Message/TestMessage/TestMessage.cs +++ b/dotnet/AipsCore/Application/Common/Message/TestMessage/TestMessage.cs @@ -2,10 +2,4 @@ using AipsCore.Application.Abstract.MessageBroking; namespace AipsCore.Application.Common.Message.TestMessage; -public record TestMessage(string Text) : IMessage -{ - public Guid? GetWhiteboardId() - { - return null; - } -} \ No newline at end of file +public record TestMessage(string Text) : IMessage; \ No newline at end of file diff --git a/dotnet/AipsRT/Hubs/WhiteboardHub.cs b/dotnet/AipsRT/Hubs/WhiteboardHub.cs index 9ff64f8..38e49f7 100644 --- a/dotnet/AipsRT/Hubs/WhiteboardHub.cs +++ b/dotnet/AipsRT/Hubs/WhiteboardHub.cs @@ -25,7 +25,7 @@ public class WhiteboardHub : Hub public async Task JoinWhiteboard(Guid whiteboardId) { if (!_whiteboardManager.WhiteboardExists(whiteboardId)) - await _whiteboardManager.AddWhiteboard(whiteboardId); + await _whiteboardManager.LoadWhiteboard(whiteboardId); await Groups.AddToGroupAsync(Context.ConnectionId, whiteboardId.ToString()); diff --git a/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs b/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs index fcdcac6..99121d6 100644 --- a/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs +++ b/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs @@ -14,7 +14,7 @@ public class WhiteboardManager _scopeFactory = scopeFactory; } - public async Task AddWhiteboard(Guid whiteboardId) + public async Task LoadWhiteboard(Guid whiteboardId) { var getWhiteboardService = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService(); var whiteboard = await getWhiteboardService.GetWhiteboard(whiteboardId); @@ -36,12 +36,12 @@ public class WhiteboardManager { var whiteboard = GetWhiteboard(whiteboardId); - if (whiteboard == null) + if (whiteboard is not null) { RemoveWhiteboard(whiteboardId); } - await AddWhiteboard(whiteboardId); + await LoadWhiteboard(whiteboardId); } public Whiteboard? GetWhiteboard(Guid whiteboardId) diff --git a/dotnet/AipsWorker/WorkerService.cs b/dotnet/AipsWorker/WorkerService.cs index c1c9b4a..b7689ec 100644 --- a/dotnet/AipsWorker/WorkerService.cs +++ b/dotnet/AipsWorker/WorkerService.cs @@ -40,24 +40,26 @@ public class WorkerService : BackgroundService private async Task HandleMessage(T message, CancellationToken ct) where T : IMessage { + Console.WriteLine($"*--------{message.GetType().Name}--------*"); + try { await _dispatcher.Execute(message, ct); - Console.WriteLine($"OK: {message.GetType().Name}"); + Console.WriteLine("OK!"); } catch (ValidationException validationException) { - var whiteboardId = message.GetWhiteboardId(); - - if (whiteboardId is not null) + if (message is IWhiteboardAwareContext) { - var errorMessage = new ErrorMessage(whiteboardId.Value, validationException.ValidationErrors); + var whiteboardId = ((IWhiteboardAwareContext)message).GetWhiteboardId(); + + var errorMessage = new ErrorMessage(whiteboardId, validationException.ValidationErrors); await _publisher.PublishAsync(errorMessage, ct); } - Console.WriteLine("===Validation Exception: "); + Console.WriteLine("Validation Exception: "); foreach (var error in validationException.ValidationErrors) { Console.WriteLine(" * Code: " + error.Code); diff --git a/front/src/stores/whiteboard.ts b/front/src/stores/whiteboard.ts index 758f350..01c7c17 100644 --- a/front/src/stores/whiteboard.ts +++ b/front/src/stores/whiteboard.ts @@ -36,6 +36,7 @@ export const useWhiteboardStore = defineStore('whiteboard', () => { isConnected.value = true whiteboardHubService.onInitWhiteboard((wb) => { + deselectShape() whiteboard.value = wb isLoading.value = false }) From 24e42f1d0b13eddb69d78675f4e51e0decad23de Mon Sep 17 00:00:00 2001 From: Andrija Stevanovic Date: Sat, 7 Mar 2026 18:13:05 +0100 Subject: [PATCH 3/3] removed unnecessary time gap prone to bug --- dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs | 12 ------------ dotnet/AipsRT/Services/RtErrorHandleStrategy.cs | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs b/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs index 99121d6..75125e6 100644 --- a/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs +++ b/dotnet/AipsRT/Model/Whiteboard/WhiteboardManager.cs @@ -32,18 +32,6 @@ public class WhiteboardManager _whiteboards.TryRemove(whiteboardId, out _); } - public async Task RefreshWhiteboard(Guid whiteboardId) - { - var whiteboard = GetWhiteboard(whiteboardId); - - if (whiteboard is not null) - { - RemoveWhiteboard(whiteboardId); - } - - await LoadWhiteboard(whiteboardId); - } - public Whiteboard? GetWhiteboard(Guid whiteboardId) { return _whiteboards.GetValueOrDefault(whiteboardId); diff --git a/dotnet/AipsRT/Services/RtErrorHandleStrategy.cs b/dotnet/AipsRT/Services/RtErrorHandleStrategy.cs index 7ce8646..3f14796 100644 --- a/dotnet/AipsRT/Services/RtErrorHandleStrategy.cs +++ b/dotnet/AipsRT/Services/RtErrorHandleStrategy.cs @@ -18,7 +18,7 @@ public class RtErrorHandleStrategy : IErrorMessageHandleStrategy public async Task Handle(ErrorMessage message, CancellationToken cancellationToken) { - await _whiteboardManager.RefreshWhiteboard(message.WhiteboardId); + await _whiteboardManager.LoadWhiteboard(message.WhiteboardId); var whiteboard = _whiteboardManager.GetWhiteboard(message.WhiteboardId)!;