From 405300b4b2fd423151809cff62be72bf4a8bee76 Mon Sep 17 00:00:00 2001 From: Viktor Lofgren Date: Wed, 4 Oct 2023 11:44:31 +0200 Subject: [PATCH] (control) Fix bug where finishing one process ad hoc task would remove all other tasks from the db --- .../control/model/TaskHeartbeat.java | 1 + .../control/svc/HeartbeatService.java | 7 +- .../control/svc/HeartbeatServiceTest.java | 73 +++++++++++++++++++ 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 code/services-core/control-service/src/test/java/nu/marginalia/control/svc/HeartbeatServiceTest.java diff --git a/code/services-core/control-service/src/main/java/nu/marginalia/control/model/TaskHeartbeat.java b/code/services-core/control-service/src/main/java/nu/marginalia/control/model/TaskHeartbeat.java index 84d5bcd5..65070cea 100644 --- a/code/services-core/control-service/src/main/java/nu/marginalia/control/model/TaskHeartbeat.java +++ b/code/services-core/control-service/src/main/java/nu/marginalia/control/model/TaskHeartbeat.java @@ -4,6 +4,7 @@ package nu.marginalia.control.model; public record TaskHeartbeat( String taskName, String taskBase, + String instanceUuidFull, String serviceUuuidFull, double lastSeenMillis, Integer progress, diff --git a/code/services-core/control-service/src/main/java/nu/marginalia/control/svc/HeartbeatService.java b/code/services-core/control-service/src/main/java/nu/marginalia/control/svc/HeartbeatService.java index 920cdf69..73cc2b23 100644 --- a/code/services-core/control-service/src/main/java/nu/marginalia/control/svc/HeartbeatService.java +++ b/code/services-core/control-service/src/main/java/nu/marginalia/control/svc/HeartbeatService.java @@ -56,7 +56,7 @@ public class HeartbeatService { List heartbeats = new ArrayList<>(); try (var conn = dataSource.getConnection(); var stmt = conn.prepareStatement(""" - SELECT TASK_NAME, TASK_BASE, SERVICE_INSTANCE, STATUS, STAGE_NAME, PROGRESS, TIMESTAMPDIFF(MICROSECOND, TASK_HEARTBEAT.HEARTBEAT_TIME, CURRENT_TIMESTAMP(6)) AS TSDIFF + SELECT TASK_NAME, TASK_BASE, INSTANCE, SERVICE_INSTANCE, STATUS, STAGE_NAME, PROGRESS, TIMESTAMPDIFF(MICROSECOND, TASK_HEARTBEAT.HEARTBEAT_TIME, CURRENT_TIMESTAMP(6)) AS TSDIFF FROM TASK_HEARTBEAT """)) { var rs = stmt.executeQuery(); @@ -65,6 +65,7 @@ public class HeartbeatService { heartbeats.add(new TaskHeartbeat( rs.getString("TASK_NAME"), rs.getString("TASK_BASE"), + rs.getString("INSTANCE"), rs.getString("SERVICE_INSTANCE"), rs.getLong("TSDIFF") / 1000., progress < 0 ? null : progress, @@ -83,10 +84,10 @@ public class HeartbeatService { try (var conn = dataSource.getConnection(); var stmt = conn.prepareStatement(""" DELETE FROM TASK_HEARTBEAT - WHERE SERVICE_INSTANCE = ? + WHERE INSTANCE = ? """)) { - stmt.setString(1, heartbeat.serviceUuuidFull()); + stmt.setString(1, heartbeat.instanceUuidFull()); stmt.executeUpdate(); } catch (SQLException ex) { diff --git a/code/services-core/control-service/src/test/java/nu/marginalia/control/svc/HeartbeatServiceTest.java b/code/services-core/control-service/src/test/java/nu/marginalia/control/svc/HeartbeatServiceTest.java new file mode 100644 index 00000000..ae2d4df5 --- /dev/null +++ b/code/services-core/control-service/src/test/java/nu/marginalia/control/svc/HeartbeatServiceTest.java @@ -0,0 +1,73 @@ +package nu.marginalia.control.svc; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import nu.marginalia.control.model.TaskHeartbeat; +import nu.marginalia.service.control.ServiceEventLog; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.mockito.Mockito; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.sql.SQLException; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.parallel.ExecutionMode.SAME_THREAD; + +@Testcontainers +@Execution(SAME_THREAD) +@Tag("slow") +class HeartbeatServiceTest { + @Container + static MariaDBContainer mariaDBContainer = new MariaDBContainer<>("mariadb") + .withDatabaseName("WMSA_prod") + .withUsername("wmsa") + .withPassword("wmsa") + .withInitScript("db/migration/V23_07_0_007__task_status.sql") + .withNetworkAliases("mariadb"); + + + static HikariDataSource dataSource; + @BeforeAll + public static void setup() { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl(mariaDBContainer.getJdbcUrl()); + config.setUsername("wmsa"); + config.setPassword("wmsa"); + + dataSource = new HikariDataSource(config); + } + + @AfterAll + public static void tearDown() { + dataSource.close(); + mariaDBContainer.close(); + } + + @Test + void removeTaskHeartbeat() throws SQLException { + var service = new HeartbeatService(dataSource, Mockito.mock(ServiceEventLog.class)); + + try (var conn = dataSource.getConnection(); + var stmt = conn.createStatement()) { + stmt.executeUpdate(""" + INSERT INTO TASK_HEARTBEAT(TASK_NAME, TASK_BASE, INSTANCE, SERVICE_INSTANCE, HEARTBEAT_TIME, STATUS) + VALUES ("test1", "test", "instance1", "instance", NOW(), "RUNNING"), + ("test2", "test", "instance2", "instance", NOW(), "RUNNING") + """); + + service.removeTaskHeartbeat(new TaskHeartbeat( + "test1", "test", "instance1", "instance", 1, null, "test", "ok") + ); + assertEquals(1, service.getTaskHeartbeats().size()); + + } + + } +} \ No newline at end of file