Skip to content

Commit

Permalink
Remove all async void functions
Browse files Browse the repository at this point in the history
  • Loading branch information
aeshub committed Nov 14, 2023
1 parent ca9c4ea commit 6fa5c61
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 67 deletions.
14 changes: 7 additions & 7 deletions backend/api/Controllers/RobotController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ [FromRoute] string missionRunId
{
string errorMessage = $"Could not reach ISAR at {robot.IsarUri}";
_logger.LogError(e, "{Message}", errorMessage);
OnIsarUnavailable(robot);
await OnIsarUnavailable(robot);
return StatusCode(StatusCodes.Status502BadGateway, errorMessage);
}
catch (MissionException e)
Expand Down Expand Up @@ -464,7 +464,7 @@ public async Task<ActionResult> StopMission([FromRoute] string robotId)
{
const string Message = "Error connecting to ISAR while stopping mission";
_logger.LogError(e, "{Message}", Message);
OnIsarUnavailable(robot);
await OnIsarUnavailable(robot);
return StatusCode(StatusCodes.Status502BadGateway, Message);
}
catch (MissionException e)
Expand Down Expand Up @@ -523,7 +523,7 @@ public async Task<ActionResult> PauseMission([FromRoute] string robotId)
{
const string Message = "Error connecting to ISAR while pausing mission";
_logger.LogError(e, "{Message}", Message);
OnIsarUnavailable(robot);
await OnIsarUnavailable(robot);
return StatusCode(StatusCodes.Status502BadGateway, Message);
}
catch (MissionException e)
Expand Down Expand Up @@ -573,7 +573,7 @@ public async Task<ActionResult> ResumeMission([FromRoute] string robotId)
{
const string Message = "Error connecting to ISAR while resuming mission";
_logger.LogError(e, "{Message}", Message);
OnIsarUnavailable(robot);
await OnIsarUnavailable(robot);
return StatusCode(StatusCodes.Status502BadGateway, Message);
}
catch (MissionException e)
Expand Down Expand Up @@ -631,7 +631,7 @@ [FromRoute] string armPosition
{
string errorMessage = $"Error connecting to ISAR at {robot.IsarUri}";
_logger.LogError(e, "{Message}", errorMessage);
OnIsarUnavailable(robot);
await OnIsarUnavailable(robot);
return StatusCode(StatusCodes.Status502BadGateway, errorMessage);
}
catch (MissionException e)
Expand Down Expand Up @@ -716,7 +716,7 @@ [FromBody] ScheduleLocalizationMissionQuery scheduleLocalizationMissionQuery
{
string message = $"Could not reach ISAR at {robot.IsarUri}";
_logger.LogError(e, "{Message}", message);
OnIsarUnavailable(robot);
await OnIsarUnavailable(robot);
return StatusCode(StatusCodes.Status502BadGateway, message);
}
catch (MissionException e)
Expand Down Expand Up @@ -747,7 +747,7 @@ [FromBody] ScheduleLocalizationMissionQuery scheduleLocalizationMissionQuery
return Ok(missionRun);
}

private async void OnIsarUnavailable(Robot robot)
private async Task OnIsarUnavailable(Robot robot)
{
robot.Enabled = false;
robot.Status = RobotStatus.Offline;
Expand Down
54 changes: 15 additions & 39 deletions backend/api/EventHandlers/MissionEventHandler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Api.Controllers.Models;
using Api.Database.Models;
using Api.Database.Models;
using Api.Services;
using Api.Services.Events;
using Api.Utilities;
Expand All @@ -11,7 +10,7 @@ public class MissionEventHandler : EventHandlerBase
private readonly ILogger<MissionEventHandler> _logger;

// The mutex is used to ensure multiple missions aren't attempted scheduled simultaneously whenever multiple mission runs are created
private readonly Mutex _scheduleMissionMutex = new();
private readonly Semaphore _scheduleMissionSemaphore = new(1, 1);
private readonly IServiceScopeFactory _scopeFactory;

public MissionEventHandler(
Expand All @@ -34,24 +33,6 @@ IServiceScopeFactory scopeFactory

private IMissionSchedulingService MissionScheduling => _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<IMissionSchedulingService>();

private IList<MissionRun> MissionRunQueue(string robotId)
{
return MissionService
.ReadAll(
new MissionRunQueryStringParameters
{
Statuses = new List<MissionStatus>
{
MissionStatus.Pending
},
RobotId = robotId,
OrderBy = "DesiredStartTime",
PageSize = 100
}
)
.Result;
}

public override void Subscribe()
{
MissionRunService.MissionRunCreated += OnMissionRunCreated;
Expand All @@ -73,27 +54,27 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
await stoppingToken;
}

private void OnMissionRunCreated(object? sender, MissionRunCreatedEventArgs e)
private async void OnMissionRunCreated(object? sender, MissionRunCreatedEventArgs e)
{
_logger.LogInformation("Triggered MissionRunCreated event for mission run ID: {MissionRunId}", e.MissionRunId);

var missionRun = MissionService.ReadById(e.MissionRunId).Result;
var missionRun = await MissionService.ReadById(e.MissionRunId);

if (missionRun == null)
{
_logger.LogError("Mission run with ID: {MissionRunId} was not found in the database", e.MissionRunId);
return;
}

if (MissionScheduling.MissionRunQueueIsEmpty(MissionRunQueue(missionRun.Robot.Id)))
if (MissionScheduling.MissionRunQueueIsEmpty(await MissionService.ReadMissionRunQueue(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();
MissionScheduling.StartMissionRunIfSystemIsAvailable(missionRun);
_scheduleMissionMutex.ReleaseMutex();
_scheduleMissionSemaphore.WaitOne();
await MissionScheduling.StartMissionRunIfSystemIsAvailable(missionRun.Id);
_scheduleMissionSemaphore.Release();
}

private async void OnRobotAvailable(object? sender, RobotAvailableEventArgs e)
Expand All @@ -106,30 +87,25 @@ private async void OnRobotAvailable(object? sender, RobotAvailableEventArgs e)
return;
}

if (MissionScheduling.MissionRunQueueIsEmpty(MissionRunQueue(robot.Id)))
if (MissionScheduling.MissionRunQueueIsEmpty(await MissionService.ReadMissionRunQueue(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 = (MissionRun?)null;

if (robot.MissionQueueFrozen)
{
missionRun = MissionRunQueue(robot.Id).FirstOrDefault(missionRun => missionRun.Robot.Id == robot.Id &&
missionRun.MissionRunPriority == MissionRunPriority.Emergency);
}
else { missionRun = MissionRunQueue(robot.Id).FirstOrDefault(missionRun => missionRun.Robot.Id == robot.Id); }
MissionRun? missionRun;
if (robot.MissionQueueFrozen) { missionRun = await MissionService.ReadNextScheduledEmergencyMissionRun(robot.Id); }
else { missionRun = await MissionService.ReadNextScheduledMissionRun(robot.Id); }

if (missionRun == null)
{
_logger.LogInformation("The robot was changed to available but no mission is scheduled");
return;
}

_scheduleMissionMutex.WaitOne();
MissionScheduling.StartMissionRunIfSystemIsAvailable(missionRun);
_scheduleMissionMutex.ReleaseMutex();
_scheduleMissionSemaphore.WaitOne();
await MissionScheduling.StartMissionRunIfSystemIsAvailable(missionRun.Id);
_scheduleMissionSemaphore.Release();
}

private async void OnEmergencyButtonPressedForRobot(object? sender, EmergencyButtonPressedForRobotEventArgs e)
Expand Down
29 changes: 29 additions & 0 deletions backend/api/Services/MissionRunService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ public interface IMissionRunService

public Task<MissionRun?> ReadByIsarMissionId(string isarMissionId);

public Task<IList<MissionRun>> ReadMissionRunQueue(string robotId);

public Task<MissionRun?> ReadNextScheduledRunByMissionId(string missionId);

public Task<MissionRun?> ReadNextScheduledMissionRun(string robotId);

public Task<MissionRun?> ReadNextScheduledEmergencyMissionRun(string robotId);

public Task<MissionRun> Update(MissionRun mission);

public Task<MissionRun> UpdateMissionRunStatusByIsarMissionId(
Expand Down Expand Up @@ -101,6 +107,29 @@ public async Task<PagedList<MissionRun>> ReadAll(MissionRunQueryStringParameters
.FirstOrDefaultAsync(missionRun => missionRun.Id.Equals(id));
}

public async Task<IList<MissionRun>> ReadMissionRunQueue(string robotId)
{
return await GetMissionRunsWithSubModels()
.Where(missionRun => missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Pending)
.OrderBy(missionRun => missionRun.DesiredStartTime)
.ToListAsync();
}

public async Task<MissionRun?> ReadNextScheduledMissionRun(string robotId)
{
return await GetMissionRunsWithSubModels()
.OrderBy(missionRun => missionRun.DesiredStartTime)
.FirstOrDefaultAsync(missionRun => missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Pending);
}

public async Task<MissionRun?> ReadNextScheduledEmergencyMissionRun(string robotId)
{
return await GetMissionRunsWithSubModels()
.OrderBy(missionRun => missionRun.DesiredStartTime)
.FirstOrDefaultAsync(missionRun =>
missionRun.Robot.Id == robotId && missionRun.MissionRunPriority == MissionRunPriority.Emergency && missionRun.Status == MissionStatus.Pending);
}

public async Task<MissionRun?> ReadNextScheduledRunByMissionId(string missionId)
{
return await GetMissionRunsWithSubModels()
Expand Down
57 changes: 36 additions & 21 deletions backend/api/Services/MissionSchedulingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Api.Services
{
public interface IMissionSchedulingService
{
public void StartMissionRunIfSystemIsAvailable(MissionRun missionRun);
public Task StartMissionRunIfSystemIsAvailable(string missionRunId);

public Task<bool> OngoingMission(string robotId);

Expand Down Expand Up @@ -47,15 +47,23 @@ public MissionSchedulingService(ILogger<MissionSchedulingService> logger, IMissi
_isarService = isarService;
}

public void StartMissionRunIfSystemIsAvailable(MissionRun missionRun)
public async Task StartMissionRunIfSystemIsAvailable(string missionRunId)
{
if (!TheSystemIsAvailableToRunAMission(missionRun.Robot, missionRun).Result)
var missionRun = await _missionRunService.ReadById(missionRunId);
if (missionRun is null)
{
string errorMessage = $"Mission run with Id {missionRunId} was not found";
_logger.LogError("{Message}", errorMessage);
throw new MissionRunNotFoundException(errorMessage);
}

if (!await TheSystemIsAvailableToRunAMission(missionRun.Robot.Id, missionRun.Id))
{
_logger.LogInformation("Mission {MissionRunId} was put on the queue as the system may not start a mission now", missionRun.Id);
return;
}

try { StartMissionRun(missionRun); }
try { await StartMissionRun(missionRun); }
catch (MissionException ex)
{
const MissionStatus NewStatus = MissionStatus.Failed;
Expand All @@ -67,7 +75,7 @@ public void StartMissionRunIfSystemIsAvailable(MissionRun missionRun)
);
missionRun.Status = NewStatus;
missionRun.StatusReason = $"Failed to start: '{ex.Message}'";
_missionRunService.Update(missionRun);
await _missionRunService.Update(missionRun);
}
}

Expand Down Expand Up @@ -115,7 +123,7 @@ public async Task StopCurrentMissionRun(string robotId)
{
const string Message = "Error connecting to ISAR while stopping mission";
_logger.LogError(e, "{Message}", Message);
OnIsarUnavailable(robot.Id);
await OnIsarUnavailable(robot.Id);
throw new MissionException(Message, (int)e.StatusCode!);
}
catch (MissionException e)
Expand Down Expand Up @@ -219,12 +227,12 @@ private async Task MoveInterruptedMissionsToQueue(IEnumerable<string> interrupte
}
}

private void StartMissionRun(MissionRun queuedMissionRun)
private async Task StartMissionRun(MissionRun queuedMissionRun)
{
var result = _robotController.StartMission(
var result = await _robotController.StartMission(
queuedMissionRun.Robot.Id,
queuedMissionRun.Id
).Result;
);
if (result.Result is not OkObjectResult)
{
string errorMessage = "Unknown error from robot controller";
Expand All @@ -237,7 +245,7 @@ private void StartMissionRun(MissionRun queuedMissionRun)
_logger.LogInformation("Started mission run '{Id}'", queuedMissionRun.Id);
}

private async void OnIsarUnavailable(string robotId)
private async Task OnIsarUnavailable(string robotId)
{
var robot = await _robotService.ReadById(robotId);
if (robot == null)
Expand Down Expand Up @@ -292,15 +300,6 @@ private static Pose ClosestSafePosition(Pose robotPose, IList<SafePosition> safe
return closestPose;
}

public async Task<bool> TheSystemIsAvailableToRunAMission(string robotId, MissionRun missionRun)
{
var robot = await _robotService.ReadById(robotId);
if (robot != null) { return await TheSystemIsAvailableToRunAMission(robot, missionRun); }

_logger.LogError("Robot with ID: {RobotId} was not found in the database", robotId);
return false;
}

private async Task<PagedList<MissionRun>?> GetOngoingMissions(string robotId)
{
var ongoingMissions = await _missionRunService.ReadAll(
Expand All @@ -318,9 +317,25 @@ public async Task<bool> TheSystemIsAvailableToRunAMission(string robotId, Missio
return ongoingMissions;
}

private async Task<bool> TheSystemIsAvailableToRunAMission(Robot robot, MissionRun missionRun)
private async Task<bool> TheSystemIsAvailableToRunAMission(string robotId, string missionRunId)
{
bool ongoingMission = await OngoingMission(robot.Id);
bool ongoingMission = await OngoingMission(robotId);

var robot = await _robotService.ReadById(robotId);
if (robot is null)
{
string errorMessage = $"Robot with ID: {robotId} was not found in the database";
_logger.LogError("{Message}", errorMessage);
throw new RobotNotFoundException(errorMessage);
}

var missionRun = await _missionRunService.ReadById(missionRunId);
if (missionRun is null)
{
string errorMessage = $"Mission run with Id {missionRunId} was not found in the database";
_logger.LogError("{Message}", errorMessage);
throw new MissionRunNotFoundException(errorMessage);
}

if (robot.MissionQueueFrozen && missionRun.MissionRunPriority != MissionRunPriority.Emergency)
{
Expand Down

0 comments on commit 6fa5c61

Please sign in to comment.