diff --git a/SingularityService/src/main/java/com/hubspot/singularity/data/history/JDBIHistoryManager.java b/SingularityService/src/main/java/com/hubspot/singularity/data/history/JDBIHistoryManager.java index 6ca97a773d..2d543ca5ff 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/data/history/JDBIHistoryManager.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/data/history/JDBIHistoryManager.java @@ -1,5 +1,6 @@ package com.hubspot.singularity.data.history; +import java.sql.SQLIntegrityConstraintViolationException; import java.util.Date; import java.util.List; import java.util.Optional; @@ -11,6 +12,7 @@ import org.slf4j.LoggerFactory; import com.codahale.metrics.annotation.Timed; +import com.google.common.base.Throwables; import com.google.inject.Inject; import com.hubspot.singularity.DeployState; import com.hubspot.singularity.ExtendedTaskState; @@ -101,8 +103,16 @@ public void saveRequestHistoryUpdate(SingularityRequestHistory requestHistory) { LOG.trace("saveRequestHistoryUpdate requestHistory {}", requestHistory); } - history.insertRequestHistory(requestHistory.getRequest().getId(), requestHistory.getRequest(), new Date(requestHistory.getCreatedAt()), - requestHistory.getEventType().name(), getUserField(requestHistory.getUser()), getMessageField(requestHistory.getMessage())); + try { + history.insertRequestHistory(requestHistory.getRequest().getId(), requestHistory.getRequest(), new Date(requestHistory.getCreatedAt()), + requestHistory.getEventType().name(), getUserField(requestHistory.getUser()), getMessageField(requestHistory.getMessage())); + } catch (Throwable t) { + if (Throwables.getCausalChain(t).stream().anyMatch((exn) -> exn instanceof SQLIntegrityConstraintViolationException)) { + LOG.info("Entry for {} ({}) already existed, skipping save", requestHistory.getRequest(), requestHistory.getCreatedAt()); + } else { + throw t; + } + } } @Override @@ -111,14 +121,22 @@ public void saveDeployHistory(SingularityDeployHistory deployHistory) { LOG.trace("saveDeployHistory {}", deployHistory); } - history.insertDeployHistory(deployHistory.getDeployMarker().getRequestId(), - deployHistory.getDeployMarker().getDeployId(), - new Date(deployHistory.getDeployMarker().getTimestamp()), - getUserField(deployHistory.getDeployMarker().getUser()), - getMessageField(deployHistory.getDeployMarker().getMessage()), - deployHistory.getDeployResult().isPresent() ? new Date(deployHistory.getDeployResult().get().getTimestamp()) : new Date(deployHistory.getDeployMarker().getTimestamp()), - deployHistory.getDeployResult().isPresent() ? deployHistory.getDeployResult().get().getDeployState().name() : DeployState.CANCELED.name(), - deployHistory); + try { + history.insertDeployHistory(deployHistory.getDeployMarker().getRequestId(), + deployHistory.getDeployMarker().getDeployId(), + new Date(deployHistory.getDeployMarker().getTimestamp()), + getUserField(deployHistory.getDeployMarker().getUser()), + getMessageField(deployHistory.getDeployMarker().getMessage()), + deployHistory.getDeployResult().isPresent() ? new Date(deployHistory.getDeployResult().get().getTimestamp()) : new Date(deployHistory.getDeployMarker().getTimestamp()), + deployHistory.getDeployResult().isPresent() ? deployHistory.getDeployResult().get().getDeployState().name() : DeployState.CANCELED.name(), + deployHistory); + } catch (Throwable t) { + if (Throwables.getCausalChain(t).stream().anyMatch((exn) -> exn instanceof SQLIntegrityConstraintViolationException)) { + LOG.info("Entry for {} - {} already existed, skipping save", deployHistory.getDeployMarker().getRequestId(), deployHistory.getDeployMarker().getDeployId()); + } else { + throw t; + } + } } @Override diff --git a/SingularityService/src/test/java/com/hubspot/singularity/SingularityHistoryTest.java b/SingularityService/src/test/java/com/hubspot/singularity/SingularityHistoryTest.java index e7272c574e..be07959f59 100644 --- a/SingularityService/src/test/java/com/hubspot/singularity/SingularityHistoryTest.java +++ b/SingularityService/src/test/java/com/hubspot/singularity/SingularityHistoryTest.java @@ -472,6 +472,17 @@ public void testMessage() { } } + @Test + public void testDuplicatePersist() { + initRequest(); + requestResource.scale(requestId, new SingularityScaleRequest(Optional.of(2), Optional.empty(), Optional.empty(), Optional.empty(), Optional.of("msg"), Optional.empty(), Optional.empty(), Optional.empty()), singularityUser); + requestHistoryPersister.runActionOnPoll(); + SingularityRequestHistory history = historyManager.getRequestHistory(requestId, Optional.of(OrderDirection.DESC), 0, 100).get(0); + historyManager.saveRequestHistoryUpdate(history); + // Should not throw exception + historyManager.saveRequestHistoryUpdate(history); + } + @Test public void testMigrateToJson() throws IOException { try(Handle handle = dbiProvider.get().open()) {