Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make event handlers more deterministic #1920

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions backend/api.test/EventHandlers/TestMissionEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -507,16 +507,14 @@ public async Task QueuedMissionsAreNotAbortedWhenRobotAvailableHappensAtTheSameT
inspectionArea,
true
);
Thread.Sleep(100);
var missionRun2 = await _databaseUtilities.NewMissionRun(
installation.InstallationCode,
robot,
inspectionArea,
true
);
Thread.Sleep(100);

var missionRunCreatedEventArgs = new MissionRunCreatedEventArgs(missionRun1.Id);
var missionRunCreatedEventArgs = new MissionRunCreatedEventArgs(missionRun1);
_missionRunService.RaiseEvent(
nameof(MissionRunService.MissionRunCreated),
missionRunCreatedEventArgs
Expand All @@ -541,7 +539,7 @@ public async Task QueuedMissionsAreNotAbortedWhenRobotAvailableHappensAtTheSameT
}
);

var robotAvailableEventArgs = new RobotAvailableEventArgs(robot.Id);
var robotAvailableEventArgs = new RobotAvailableEventArgs(robot);

_mqttService.RaiseEvent(
nameof(MqttService.MqttIsarMissionReceived),
Expand All @@ -551,7 +549,6 @@ public async Task QueuedMissionsAreNotAbortedWhenRobotAvailableHappensAtTheSameT
nameof(MissionSchedulingService.RobotAvailable),
robotAvailableEventArgs
);
Thread.Sleep(500);

// Assert
var postTestMissionRun1 = await _missionRunService.ReadById(
Expand Down Expand Up @@ -600,7 +597,7 @@ public async Task QueuedContinuesWhenOnIsarStatusHappensAtTheSameTimeAsOnIsarMis
);
Thread.Sleep(100);

var missionRunCreatedEventArgs = new MissionRunCreatedEventArgs(missionRun1.Id);
var missionRunCreatedEventArgs = new MissionRunCreatedEventArgs(missionRun1);
_missionRunService.RaiseEvent(
nameof(MissionRunService.MissionRunCreated),
missionRunCreatedEventArgs
Expand Down Expand Up @@ -692,7 +689,7 @@ public async Task ReturnHomeMissionAbortedIfNewMissionScheduled()
Thread.Sleep(100);

// Act
var eventArgs = new MissionRunCreatedEventArgs(missionRun.Id);
var eventArgs = new MissionRunCreatedEventArgs(missionRun);
_missionRunService.RaiseEvent(nameof(MissionRunService.MissionRunCreated), eventArgs);
Thread.Sleep(500);

Expand Down
2 changes: 1 addition & 1 deletion backend/api.test/Services/RobotService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public async Task Read()
);
var installation = await _databaseUtilities.ReadOrNewInstallation();
var robot = await _databaseUtilities.NewRobot(RobotStatus.Available, installation);
var robotById = await robotService.ReadById(robot.Id, readOnly: false);
var robotById = await robotService.ReadById(robot.Id, readOnly: true);
Assert.NotNull(robotById);
Assert.Equal(robot.Id, robotById.Id);
}
Expand Down
10 changes: 2 additions & 8 deletions backend/api/Controllers/EmergencyActionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,7 @@ [FromRoute] string installationCode
foreach (var robot in robots)
{
emergencyActionService.SendRobotToDock(
new RobotEmergencyEventArgs(
robot.Id,
Database.Models.RobotFlotillaStatus.Docked
)
new RobotEmergencyEventArgs(robot, Database.Models.RobotFlotillaStatus.Docked)
);
}

Expand Down Expand Up @@ -77,10 +74,7 @@ [FromRoute] string installationCode
foreach (var robot in robots)
{
emergencyActionService.ReleaseRobotFromDock(
new RobotEmergencyEventArgs(
robot.Id,
Database.Models.RobotFlotillaStatus.Normal
)
new RobotEmergencyEventArgs(robot, Database.Models.RobotFlotillaStatus.Normal)
);
}

Expand Down
2 changes: 1 addition & 1 deletion backend/api/Controllers/RobotController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ [FromBody] RobotStatus robotStatus

if (robotStatus == RobotStatus.Available)
missionSchedulingService.TriggerRobotAvailable(
new RobotAvailableEventArgs(robot.Id)
new RobotAvailableEventArgs(robot)
);

return Ok(robotResponse);
Expand Down
4 changes: 1 addition & 3 deletions backend/api/EventHandlers/IsarConnectionEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ private async void OnIsarRobotHeartbeat(object? sender, MqttReceivedArgs mqttArg
// If the robot became available while the connection was not active, then this will not be triggered
// It will however be triggered if the robot lost connection while restarting or while idle
if (robot.Status == RobotStatus.Available)
MissionSchedulingService.TriggerRobotAvailable(
new RobotAvailableEventArgs(robot.Id)
);
MissionSchedulingService.TriggerRobotAvailable(new RobotAvailableEventArgs(robot));
}

private void AddTimerForRobot(IsarRobotHeartbeatMessage isarRobotHeartbeat, Robot robot)
Expand Down
84 changes: 18 additions & 66 deletions backend/api/EventHandlers/MissionEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ IServiceScopeFactory scopeFactory
Subscribe();
}

private IMissionRunService MissionService =>
_scopeFactory.CreateScope().ServiceProvider.GetRequiredService<IMissionRunService>();

private IRobotService RobotService =>
_scopeFactory.CreateScope().ServiceProvider.GetRequiredService<IRobotService>();

Expand Down Expand Up @@ -65,21 +62,13 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)

private async void OnMissionRunCreated(object? sender, MissionRunCreatedEventArgs e)
{
var missionRun = e.MissionRun;

_logger.LogInformation(
"Triggered MissionRunCreated event for mission run ID: {MissionRunId}",
e.MissionRunId
missionRun.Id
);

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

_startMissionSemaphore.WaitOne();

if (
Expand Down Expand Up @@ -109,24 +98,10 @@ private async void OnMissionRunCreated(object? sender, MissionRunCreatedEventArg

private async void OnRobotAvailable(object? sender, RobotAvailableEventArgs e)
{
_logger.LogInformation(
"Triggered RobotAvailable event for robot ID: {RobotId}",
e.RobotId
);
var robot = await RobotService.ReadById(e.RobotId, readOnly: true);
if (robot == null)
{
_logger.LogError(
"Robot with ID: {RobotId} was not found in the database",
e.RobotId
);
return;
}

_startMissionSemaphore.WaitOne();
try
{
await MissionScheduling.StartNextMissionRunIfSystemIsAvailable(robot);
await MissionScheduling.StartNextMissionRunIfSystemIsAvailable(e.Robot);
andchiind marked this conversation as resolved.
Show resolved Hide resolved
}
catch (MissionRunNotFoundException)
{
Expand All @@ -140,23 +115,16 @@ private async void OnRobotAvailable(object? sender, RobotAvailableEventArgs e)

private async void OnSendRobotToDockTriggered(object? sender, RobotEmergencyEventArgs e)
{
var robot = e.Robot;

_logger.LogInformation(
"Triggered EmergencyButtonPressed event for robot ID: {RobotId}",
e.RobotId
robot.Id
);
var robot = await RobotService.ReadById(e.RobotId, readOnly: true);
if (robot == null)
{
_logger.LogError(
"Robot with ID: {RobotId} was not found in the database",
e.RobotId
);
return;
}

try
{
await MissionScheduling.FreezeMissionRunQueueForRobot(e.RobotId);
await MissionScheduling.FreezeMissionRunQueueForRobot(robot.Id);
}
catch (RobotNotFoundException)
{
Expand All @@ -167,28 +135,28 @@ private async void OnSendRobotToDockTriggered(object? sender, RobotEmergencyEven
{
_logger.LogInformation(
"Did not send robot to Dock since robot {RobotId} was already in the correct state",
e.RobotId
robot.Id
);
return;
}

try
{
await RobotService.UpdateFlotillaStatus(e.RobotId, e.RobotFlotillaStatus);
await RobotService.UpdateFlotillaStatus(robot.Id, e.RobotFlotillaStatus);
}
catch (Exception ex)
{
_logger.LogError(
"Was not able to update Robot Flotilla status for robot {RobotId}, {ErrorMessage}",
e.RobotId,
robot.Id,
ex.Message
);
return;
}

try
{
await MissionScheduling.ScheduleMissionToDriveToDockPosition(e.RobotId);
await MissionScheduling.ScheduleMissionToDriveToDockPosition(robot.Id);
}
catch (DockException ex)
{
Expand All @@ -206,7 +174,7 @@ private async void OnSendRobotToDockTriggered(object? sender, RobotEmergencyEven

try
{
await MissionScheduling.StopCurrentMissionRun(e.RobotId);
await MissionScheduling.StopCurrentMissionRun(robot.Id);
}
catch (RobotNotFoundException)
{
Expand Down Expand Up @@ -266,28 +234,12 @@ private async void OnReleaseRobotFromDockTriggered(
RobotEmergencyEventArgs e
)
{
var robot = e.Robot;

_logger.LogInformation(
"Triggered EmergencyButtonPressed event for robot ID: {RobotId}",
e.RobotId
e.Robot.Id
);
var robot = await RobotService.ReadById(e.RobotId, readOnly: true);
if (robot == null)
{
_logger.LogError(
"Robot with ID: {RobotId} was not found in the database",
e.RobotId
);
return;
}

if (robot.FlotillaStatus == e.RobotFlotillaStatus)
{
_logger.LogInformation(
"Did not release robot from Dock since robot {RobotId} was already in the correct state",
e.RobotId
);
return;
}

try
{
Expand All @@ -302,13 +254,13 @@ RobotEmergencyEventArgs e

try
{
await RobotService.UpdateFlotillaStatus(e.RobotId, e.RobotFlotillaStatus);
await RobotService.UpdateFlotillaStatus(robot.Id, e.RobotFlotillaStatus);
}
catch (Exception ex)
{
_logger.LogError(
"Was not able to update Robot Flotilla status for robot {RobotId}, {ErrorMessage}",
e.RobotId,
robot.Id,
ex.Message
);
return;
Expand Down
8 changes: 4 additions & 4 deletions backend/api/EventHandlers/MqttEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ private async void OnIsarBatteryUpdate(object? sender, MqttReceivedArgs mqttArgs
robot.Name
);
EmergencyActionService.SendRobotToDock(
new RobotEmergencyEventArgs(robot.Id, RobotFlotillaStatus.Recharging)
new RobotEmergencyEventArgs(robot, RobotFlotillaStatus.Recharging)
andchiind marked this conversation as resolved.
Show resolved Hide resolved
);
}
else if (
Expand All @@ -586,7 +586,7 @@ private async void OnIsarBatteryUpdate(object? sender, MqttReceivedArgs mqttArgs
robot.Name
);
EmergencyActionService.ReleaseRobotFromDock(
new RobotEmergencyEventArgs(robot.Id, RobotFlotillaStatus.Normal)
new RobotEmergencyEventArgs(robot, RobotFlotillaStatus.Normal)
);
}
}
Expand Down Expand Up @@ -620,7 +620,7 @@ private async void OnIsarPressureUpdate(object? sender, MqttReceivedArgs mqttArg
robot.Name
);
EmergencyActionService.SendRobotToDock(
new RobotEmergencyEventArgs(robot.Id, RobotFlotillaStatus.Recharging)
new RobotEmergencyEventArgs(robot, RobotFlotillaStatus.Recharging)
);
}
else if (
Expand All @@ -633,7 +633,7 @@ private async void OnIsarPressureUpdate(object? sender, MqttReceivedArgs mqttArg
robot.Name
);
EmergencyActionService.ReleaseRobotFromDock(
new RobotEmergencyEventArgs(robot.Id, RobotFlotillaStatus.Normal)
new RobotEmergencyEventArgs(robot, RobotFlotillaStatus.Normal)
);
}
}
Expand Down
12 changes: 6 additions & 6 deletions backend/api/Services/Events/MissionEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

namespace Api.Services.Events
{
public class MissionRunCreatedEventArgs(string missionRunId) : EventArgs
public class MissionRunCreatedEventArgs(MissionRun missionRun) : EventArgs
{
public string MissionRunId { get; } = missionRunId;
public MissionRun MissionRun { get; } = missionRun;
}

public class RobotAvailableEventArgs(string robotId) : EventArgs
public class RobotAvailableEventArgs(Robot robot) : EventArgs
{
public string RobotId { get; } = robotId;
public Robot Robot { get; } = robot;
}

public class RobotEmergencyEventArgs(string robotId, RobotFlotillaStatus robotFlotillaStatus)
public class RobotEmergencyEventArgs(Robot robot, RobotFlotillaStatus robotFlotillaStatus)
: EventArgs
{
public string RobotId { get; } = robotId;
public Robot Robot { get; } = robot;
public RobotFlotillaStatus RobotFlotillaStatus { get; } = robotFlotillaStatus;
}

Expand Down
6 changes: 3 additions & 3 deletions backend/api/Services/MissionRunService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,11 @@ public async Task<MissionRun> Create(
new MissionRunResponse(missionRun)
);

DetachTracking(missionRun);

if (triggerCreatedMissionRunEvent)
{
var args = new MissionRunCreatedEventArgs(missionRun.Id);
var args = new MissionRunCreatedEventArgs(missionRun);
OnMissionRunCreated(args);
}

Expand All @@ -152,8 +154,6 @@ public async Task<MissionRun> Create(
logger.LogInformation($"Mission run created by user with Id {userInfo.Id}");
}

DetachTracking(missionRun);

return missionRun;
}

Expand Down
2 changes: 1 addition & 1 deletion backend/api/Services/RobotService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ private async Task UpdateRobotProperty(
bool isLogLevelDebug = false
)
{
var robot = await ReadById(robotId, readOnly: false);
var robot = await ReadById(robotId, readOnly: true);
if (robot is null)
{
string errorMessage = $"Robot with ID {robotId} was not found in the database";
Expand Down
Loading