Skip to content

Commit

Permalink
Merge pull request #1243 from NASA-AMMOS/feat/cancel-simulation
Browse files Browse the repository at this point in the history
Cancel Running Simulations
  • Loading branch information
Mythicaeda authored Nov 21, 2023
2 parents 936dae1 + cf91ec6 commit 9fa3cd4
Show file tree
Hide file tree
Showing 31 changed files with 570 additions and 298 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -606,158 +606,6 @@ SELECT COUNT(*)
}
}
}

@Test
void shouldCancelSimulationOnMissionModelUpdate() throws SQLException {
try (final var statement = connection.createStatement()) {
try (final var res = statement.executeQuery(
"""
SELECT canceled
FROM simulation_dataset
WHERE simulation_id = %s;"""
.formatted(simulationDatasetRecord.simulation_id())
)
) {
res.next();
assertFalse(res.getBoolean("canceled"));
}

statement
.executeUpdate(
"""
UPDATE mission_model
SET name = 'updated-name-%s'
WHERE id = %s;"""
.formatted(UUID.randomUUID().toString(), missionModelId)
);

try (final var res = statement.executeQuery(
"""
SELECT canceled
FROM simulation_dataset
WHERE simulation_id = %s;"""
.formatted(simulationDatasetRecord.simulation_id())
)
) {
res.next();
assertTrue(res.getBoolean("canceled"));
}
}
}

@Test
void shouldCancelSimulationOnPlanUpdate() throws SQLException {
try (final var statement = connection.createStatement()) {
try (final var res = statement.executeQuery(
"""
SELECT canceled
FROM simulation_dataset
WHERE simulation_id = %s;"""
.formatted(simulationDatasetRecord.simulation_id())
)
) {
res.next();
assertFalse(res.getBoolean("canceled"));
}

statement
.executeUpdate(
"""
UPDATE plan
SET name = 'test-plan-updated-%s'
WHERE id = %s;"""
.formatted(UUID.randomUUID().toString(), planId)
);

try (final var res = statement.executeQuery(
"""
SELECT canceled
FROM simulation_dataset
WHERE simulation_id = %s;"""
.formatted(simulationDatasetRecord.simulation_id())
)
) {
res.next();
assertTrue(res.getBoolean("canceled"));
}
}
}

@Test
void shouldCancelSimulationOnSimulationUpdate() throws SQLException {
try (final var statement = connection.createStatement()) {
try (final var res = statement.executeQuery(
"""
SELECT canceled
FROM simulation_dataset
WHERE simulation_id = %s;"""
.formatted(simulationDatasetRecord.simulation_id())
)
) {
res.next();
assertFalse(res.getBoolean("canceled"));
}

statement
.executeUpdate(
"""
UPDATE simulation
SET arguments = '{}'
WHERE id = %s;"""
.formatted(simulationId)
);

try (final var res = statement.executeQuery(
"""
SELECT canceled
FROM simulation_dataset
WHERE simulation_id = %s;"""
.formatted(simulationDatasetRecord.simulation_id())
)
) {
res.next();
assertTrue(res.getBoolean("canceled"));
}
}
}

@Test
void shouldCancelSimulationOnSimulationTemplateUpdate() throws SQLException {
try (final var statement = connection.createStatement()) {
try (final var res = statement.executeQuery(
"""
SELECT canceled
FROM simulation_dataset
WHERE simulation_id = %s;"""
.formatted(simulationDatasetRecord.simulation_id())
)
) {
res.next();
assertFalse(res.getBoolean("canceled"));
}

statement
.executeUpdate(
"""
UPDATE simulation_template
SET description = 'test-description-updated'
WHERE id = %s;"""
.formatted(simulationTemplateId)
);

try (final var res = statement.executeQuery(
"""
SELECT canceled
FROM simulation_dataset
WHERE simulation_id = %s;"""
.formatted(simulationDatasetRecord.simulation_id())
)
) {
res.next();
assertTrue(res.getBoolean("canceled"));
}
}
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
-- Drop notify
drop trigger notify_simulation_workers_cancel on simulation_dataset;
drop function notify_simulation_workers_cancel();

-- "Recancel" all old sims
with latest_revisions(simulation_id, simulation_rev, plan_rev, model_rev, sim_template_rev) as (
select s.id, s.revision, p.revision, m.revision, st.revision
from simulation s
left join plan p on s.plan_id = p.id
left join mission_model m on p.model_id = m.id
left join simulation_template st on s.simulation_template_id = st.id
)
update simulation_dataset sd
set canceled = true
from latest_revisions lr
where sd.simulation_id = lr.simulation_id
and (sd.plan_revision is distinct from lr.plan_rev
or sd.model_revision is distinct from lr.model_rev
or sd.simulation_template_revision is distinct from lr.sim_template_rev
or sd.simulation_revision is distinct from lr.simulation_rev);

-- Restore cancel triggers
create function cancel_on_mission_model_update()
returns trigger
security definer
language plpgsql as $$begin
with
sim_info as
( select
sim.id as sim_id,
model.id as model_id
from simulation as sim
left join plan on sim.plan_id = plan.id
left join mission_model as model on plan.model_id = model.id)
update simulation_dataset
set canceled = true
where simulation_id in (select sim_id from sim_info where model_id = new.id);
return new;
end$$;

create function cancel_on_plan_update()
returns trigger
security definer
language plpgsql as $$begin
update simulation_dataset
set canceled = true
where simulation_id in (select id from simulation where plan_id = new.id);
return new;
end$$;

create function cancel_on_simulation_update()
returns trigger
security definer
language plpgsql as $$begin
update simulation_dataset
set canceled = true
where simulation_id = new.id;
return new;
end$$;

create function cancel_on_simulation_template_update()
returns trigger
security definer
language plpgsql as $$begin
update simulation_dataset
set canceled = true
where simulation_id in (select id from simulation where simulation_template_id = new.id);
return new;
end$$;

do $$ begin
create trigger cancel_on_mission_model_update_trigger
after update on mission_model
for each row
execute function cancel_on_mission_model_update();
exception
when duplicate_object then null;
end $$;

do $$ begin
create trigger cancel_on_plan_update_trigger
after update on plan
for each row
execute function cancel_on_plan_update();
exception
when duplicate_object then null;
end $$;

do $$ begin
create trigger cancel_on_simulation_update_trigger
after update on simulation
for each row
execute function cancel_on_simulation_update();
exception
when duplicate_object then null;
end $$;

do $$ begin
create trigger cancel_on_simulation_template_update_trigger
after update on simulation_template
for each row
execute function cancel_on_simulation_template_update();
exception
when duplicate_object then null;
end $$;

call migrations.mark_migration_rolled_back('33');
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
-- Turn off the cancel triggers
drop trigger cancel_on_simulation_template_update_trigger on simulation_template;
drop trigger cancel_on_simulation_update_trigger on simulation;
drop trigger cancel_on_plan_update_trigger on plan;
drop trigger cancel_on_mission_model_update_trigger on mission_model;

drop function cancel_on_simulation_template_update();
drop function cancel_on_simulation_update();
drop function cancel_on_plan_update();
drop function cancel_on_mission_model_update();

-- "Uncancel" all completed sims marked as canceled by the auto triggers
update simulation_dataset
set canceled = false
where status = 'success' or status = 'failed';

-- Send notify on cancel
create function notify_simulation_workers_cancel()
returns trigger
security definer
language plpgsql as $$
begin
perform pg_notify('simulation_cancel', '' || new.dataset_id);
return null;
end
$$;

create trigger notify_simulation_workers_cancel
after update of canceled on simulation_dataset
for each row
when ( (old.status != 'success' or old.status != 'failed') and new.canceled )
execute function notify_simulation_workers_cancel();

call migrations.mark_migration_applied('33');

1 change: 1 addition & 0 deletions e2e-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ task e2eTest(type: Test) {
}

dependsOn ":examples:banananation:assemble"
dependsOn ":examples:foo-missionmodel:assemble"

if(file('.env').exists()) {
parseEnvFile('.env')
Expand Down
Loading

0 comments on commit 9fa3cd4

Please sign in to comment.