Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.SneakyThrows;
Expand Down Expand Up @@ -120,9 +118,6 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
private static final String PATCH_FIELDS =
"owners,entityLink,testSuite,testSuites,testDefinition,computePassedFailedRowCount,useDynamicAssertion,dimensionColumns,topDimensions";
public static final String FAILED_ROWS_SAMPLE_EXTENSION = "testCase.failedRowsSample";
private final ExecutorService asyncExecutor =
Executors.newFixedThreadPool(
1, java.lang.Thread.ofPlatform().name("om-test-case-async").factory());

public TestCaseRepository() {
super(
Expand Down Expand Up @@ -896,18 +891,12 @@ private void updateLogicalTestSuite(UUID testSuiteId) {
protected void deleteChildren(
List<CollectionDAO.EntityRelationshipRecord> children, boolean hardDelete, String updatedBy) {
if (hardDelete) {
for (CollectionDAO.EntityRelationshipRecord entityRelationshipRecord : children) {
LOG.info(
"Recursively {} deleting {} {}",
hardDelete ? "hard" : "soft",
entityRelationshipRecord.getType(),
entityRelationshipRecord.getId());
TestCaseResolutionStatusRepository testCaseResolutionStatusRepository =
(TestCaseResolutionStatusRepository)
Entity.getEntityTimeSeriesRepository(Entity.TEST_CASE_RESOLUTION_STATUS);
for (CollectionDAO.EntityRelationshipRecord child : children) {
testCaseResolutionStatusRepository.deleteById(child.getId(), hardDelete);
}
TestCaseResolutionStatusRepository testCaseResolutionStatusRepository =
(TestCaseResolutionStatusRepository)
Entity.getEntityTimeSeriesRepository(Entity.TEST_CASE_RESOLUTION_STATUS);
for (CollectionDAO.EntityRelationshipRecord child : children) {
LOG.info("Hard deleting {} {}", child.getType(), child.getId());
testCaseResolutionStatusRepository.deleteById(child.getId(), hardDelete);
}
}
}
Expand All @@ -921,14 +910,6 @@ private void deleteAllTestCaseResults(String fqn) {
TestCaseResultRepository testCaseResultRepository =
(TestCaseResultRepository) Entity.getEntityTimeSeriesRepository(TEST_CASE_RESULT);
testCaseResultRepository.deleteAllTestCaseResults(fqn);
asyncExecutor.submit(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RajdeepKushwaha5 any reason you removed the async excecutor here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harshach

The current code calls deleteAllTestCaseResults(fqn) twice — once synchronously and then the exact same call again via asyncExecutor.submit():

testCaseResultRepository.deleteAllTestCaseResults(fqn);     // deletes everything right here
asyncExecutor.submit(() -> {
    testCaseResultRepository.deleteAllTestCaseResults(fqn);  // runs later, finds nothing to delete
});

The sync call finishes and wipes all the results before the async task even starts, so the async one always ends up being a no-op — it just executes the same DELETEs against rows that no longer exist.

I kept the sync call and removed the async one (rather than the other way around) because deleteAllTestCaseResults() is called from entitySpecificCleanup(), which runs inside the JDBI transaction in cleanup(). The sync call participates in that transaction — so if anything downstream fails and the transaction rolls back, the results stay intact (consistent with the test case not being deleted). If we kept only the async call, it would run on a separate thread outside the transaction, meaning it could delete results even when the parent entity deletion rolled back.

So basically: the async call was redundant (double-delete), and the sync one is the correct one to keep for transactional safety.

Happy to restructure if you'd prefer a different approach — just let me know!

() -> {
try {
testCaseResultRepository.deleteAllTestCaseResults(fqn);
} catch (Exception e) {
LOG.error("Error deleting test case results for test case {}", fqn, e);
}
});
}

@SneakyThrows
Expand Down
Loading