From 138f66e5cb270b556241837a470234d6b08f32bf Mon Sep 17 00:00:00 2001 From: aestene Date: Fri, 18 Aug 2023 13:21:02 +0200 Subject: [PATCH] Use robot specific mission run queues --- .../EventHandlers/TestMissionEventHandler.cs | 35 ++++++++++++++ .../api/EventHandlers/MissionEventHandler.cs | 48 ++++++++++--------- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/backend/api.test/EventHandlers/TestMissionEventHandler.cs b/backend/api.test/EventHandlers/TestMissionEventHandler.cs index a26e9e28..b5f866b6 100644 --- a/backend/api.test/EventHandlers/TestMissionEventHandler.cs +++ b/backend/api.test/EventHandlers/TestMissionEventHandler.cs @@ -281,6 +281,41 @@ public async void NoMissionIsStartedIfQueueIsEmptyWhenRobotBecomesAvailable() Assert.False(ongoingMission); } + [Fact] + public async void MissionRunIsStartedForOtherAvailableRobotIfOneRobotHasAnOngoingMissionRun() + { + // Arrange + var robotOne = await NewRobot(RobotStatus.Available); + var robotTwo = await NewRobot(RobotStatus.Available); + await _robotService.Create(robotOne); + await _robotService.Create(robotTwo); + + var missionRunOne = ScheduledMission; + var missionRunTwo = ScheduledMission; + + missionRunOne.Robot = robotOne; + missionRunTwo.Robot = robotTwo; + + SetupMocksForRobotController(robotOne, missionRunOne); + + // Act (Ensure first mission is started) + await _missionRunService.Create(missionRunOne); + + // Assert + var postStartMissionRunOne = await _missionRunService.ReadById(missionRunOne.Id); + Assert.Equal(MissionStatus.Ongoing, postStartMissionRunOne.Status); + + // Rearrange + SetupMocksForRobotController(robotTwo, missionRunTwo); + + // Act (Ensure second mission is started for second robot) + await _missionRunService.Create(missionRunTwo); + + // Assert + var postStartMissionTunTwo = await _missionRunService.ReadById(missionRunTwo.Id); + Assert.Equal(MissionStatus.Ongoing, postStartMissionTunTwo.Status); + } + private void SetupMocksForRobotController(Robot robot, MissionRun missionRun) { _robotControllerMock.IsarServiceMock diff --git a/backend/api/EventHandlers/MissionEventHandler.cs b/backend/api/EventHandlers/MissionEventHandler.cs index 99997c75..fa3fa4ef 100644 --- a/backend/api/EventHandlers/MissionEventHandler.cs +++ b/backend/api/EventHandlers/MissionEventHandler.cs @@ -26,8 +26,17 @@ IServiceScopeFactory scopeFactory Subscribe(); } - private IList MissionRunQueue => - MissionService + private IMissionRunService MissionService => + _scopeFactory.CreateScope().ServiceProvider.GetRequiredService(); + + private IRobotService RobotService => _scopeFactory.CreateScope().ServiceProvider.GetRequiredService(); + + private RobotController RobotController => + _scopeFactory.CreateScope().ServiceProvider.GetRequiredService(); + + private IList MissionRunQueue(string robotId) + { + return MissionService .ReadAll( new MissionRunQueryStringParameters { @@ -35,19 +44,13 @@ IServiceScopeFactory scopeFactory { MissionStatus.Pending }, + RobotId = robotId, OrderBy = "DesiredStartTime", PageSize = 100 } ) .Result; - - private IMissionRunService MissionService => - _scopeFactory.CreateScope().ServiceProvider.GetRequiredService(); - - private IRobotService RobotService => _scopeFactory.CreateScope().ServiceProvider.GetRequiredService(); - - private RobotController RobotController => - _scopeFactory.CreateScope().ServiceProvider.GetRequiredService(); + } public override void Subscribe() { @@ -70,12 +73,6 @@ private void OnMissionRunCreated(object? sender, MissionRunCreatedEventArgs e) { _logger.LogInformation("Triggered MissionRunCreated event for mission run ID: {MissionRunId}", e.MissionRunId); - if (MissionRunQueueIsEmpty()) - { - _logger.LogInformation("Mission run {MissionRunId} was not started as there are no mission runs on the queue", e.MissionRunId); - return; - } - var missionRun = MissionService.ReadById(e.MissionRunId).Result; if (missionRun == null) @@ -84,6 +81,12 @@ private void OnMissionRunCreated(object? sender, MissionRunCreatedEventArgs e) return; } + if (MissionRunQueueIsEmpty(MissionRunQueue(missionRun.Robot.Id))) + { + _logger.LogInformation("Mission run {MissionRunId} was not started as there are no mission runs on the queue", e.MissionRunId); + return; + } + _scheduleMissionMutex.WaitOne(); StartMissionRunIfSystemIsAvailable(missionRun); _scheduleMissionMutex.ReleaseMutex(); @@ -99,13 +102,13 @@ private async void OnRobotAvailable(object? sender, RobotAvailableEventArgs e) return; } - if (MissionRunQueueIsEmpty()) + if (MissionRunQueueIsEmpty(MissionRunQueue(robot.Id))) { _logger.LogInformation("The robot was changed to available but there are no mission runs in the queue to be scheduled"); return; } - var missionRun = MissionRunQueue.First(missionRun => missionRun.Robot.Id == robot.Id); + var missionRun = MissionRunQueue(robot.Id).First(missionRun => missionRun.Robot.Id == robot.Id); _scheduleMissionMutex.WaitOne(); StartMissionRunIfSystemIsAvailable(missionRun); @@ -139,14 +142,14 @@ private void StartMissionRunIfSystemIsAvailable(MissionRun missionRun) } } - private bool MissionRunQueueIsEmpty() + private static bool MissionRunQueueIsEmpty(IList missionRunQueue) { - return !MissionRunQueue.Any(); + return !missionRunQueue.Any(); } private async Task TheSystemIsAvailableToRunAMission(Robot robot, MissionRun missionRun) { - bool ongoingMission = await OngoingMission(); + bool ongoingMission = await OngoingMission(robot.Id); if (ongoingMission) { @@ -171,7 +174,7 @@ private async Task TheSystemIsAvailableToRunAMission(Robot robot, MissionR return true; } - private async Task OngoingMission() + private async Task OngoingMission(string robotId) { var ongoingMissions = await MissionService.ReadAll( new MissionRunQueryStringParameters @@ -180,6 +183,7 @@ private async Task OngoingMission() { MissionStatus.Ongoing }, + RobotId = robotId, OrderBy = "DesiredStartTime", PageSize = 100 });