Skip to content

Commit 2c1291a

Browse files
committed
fixed timer which deletes old triggers
1 parent 1dbbf11 commit 2c1291a

File tree

8 files changed

+99
-34
lines changed

8 files changed

+99
-34
lines changed

core/src/main/java/org/sterl/spring/persistent_tasks/history/HistoryService.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import org.sterl.spring.persistent_tasks.history.model.HistoryTriggerEntity;
2222
import org.sterl.spring.persistent_tasks.history.model.QCompletedTriggerEntity;
2323
import org.sterl.spring.persistent_tasks.history.repository.CompletedTriggerRepository;
24-
import org.sterl.spring.persistent_tasks.history.repository.TriggerHistoryDetailRepository;
24+
import org.sterl.spring.persistent_tasks.history.repository.HistoryTriggerRepository;
2525
import org.sterl.spring.persistent_tasks.shared.QueryHelper;
2626
import org.sterl.spring.persistent_tasks.shared.model.HasTrigger;
2727
import org.sterl.spring.persistent_tasks.shared.stereotype.TransactionalService;
@@ -36,7 +36,7 @@
3636
public class HistoryService {
3737
private final EntityManager em;
3838
private final CompletedTriggerRepository completedTriggerRepository;
39-
private final TriggerHistoryDetailRepository triggerHistoryDetailRepository;
39+
private final HistoryTriggerRepository historyTriggerRepository;
4040
private final ApplicationEventPublisher applicationEventPublisher;
4141

4242
public Optional<CompletedTriggerEntity> findStatus(long triggerId) {
@@ -51,11 +51,11 @@ public Optional<CompletedTriggerEntity> findLastKnownStatus(TriggerKey triggerKe
5151

5252
public void deleteAll() {
5353
completedTriggerRepository.deleteAllInBatch();
54-
triggerHistoryDetailRepository.deleteAllInBatch();
54+
historyTriggerRepository.deleteAllInBatch();
5555
}
5656

5757
public long deleteAllOlderThan(OffsetDateTime age) {
58-
var result = triggerHistoryDetailRepository.deleteOlderThan(age);
58+
var result = historyTriggerRepository.deleteOlderThan(age);
5959
result += completedTriggerRepository.deleteOlderThan(age);
6060
return result;
6161
}
@@ -64,12 +64,12 @@ public long deleteAllOlderThan(OffsetDateTime age) {
6464
* Counts the <b>unique</b> triggers in the history.
6565
*/
6666
public long countTriggers(TriggerStatus status) {
67-
return triggerHistoryDetailRepository.countByStatus(status);
67+
return historyTriggerRepository.countByStatus(status);
6868
}
6969

7070
public Page<HistoryTriggerEntity> findAllDetailsForInstance(long instanceId, Pageable page) {
7171
page = QueryHelper.applySortIfEmpty(page, Sort.by(Direction.DESC, "id"));
72-
return triggerHistoryDetailRepository.findAllByInstanceId(instanceId, page);
72+
return historyTriggerRepository.findAllByInstanceId(instanceId, page);
7373
}
7474

7575
public Optional<TriggerKey> reQueue(Long id, OffsetDateTime runAt) {

core/src/main/java/org/sterl/spring/persistent_tasks/history/component/TriggerHistoryComponent.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.sterl.spring.persistent_tasks.history.component;
22

3-
import org.apache.commons.lang3.StringUtils;
43
import org.springframework.context.event.EventListener;
54
import org.springframework.scheduling.annotation.Async;
65
import org.springframework.stereotype.Component;
@@ -11,7 +10,7 @@
1110
import org.sterl.spring.persistent_tasks.history.model.CompletedTriggerEntity;
1211
import org.sterl.spring.persistent_tasks.history.model.HistoryTriggerEntity;
1312
import org.sterl.spring.persistent_tasks.history.repository.CompletedTriggerRepository;
14-
import org.sterl.spring.persistent_tasks.history.repository.TriggerHistoryDetailRepository;
13+
import org.sterl.spring.persistent_tasks.history.repository.HistoryTriggerRepository;
1514
import org.sterl.spring.persistent_tasks.shared.model.TriggerEntity;
1615
import org.sterl.spring.persistent_tasks.trigger.event.TriggerLifeCycleEvent;
1716
import org.sterl.spring.persistent_tasks.trigger.event.TriggerRunningEvent;
@@ -25,7 +24,7 @@
2524
public class TriggerHistoryComponent {
2625

2726
private final CompletedTriggerRepository completedTriggerRepository;
28-
private final TriggerHistoryDetailRepository triggerHistoryDetailRepository;
27+
private final HistoryTriggerRepository historyTriggerRepository;
2928

3029
// we have to ensure to run in an own transaction
3130
// as if the trigger fails, a rollback would also remove this entry
@@ -45,11 +44,11 @@ public void onRunning(TriggerRunningEvent e) {
4544
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
4645
void onPersistentTaskEvent(TriggerLifeCycleEvent e) {
4746
if (e instanceof TriggerRunningEvent) return; // we have an own listener for that
47+
4848
log.debug("Received event={} for {} new status={}",
4949
e.getClass().getSimpleName(),
5050
e.key(), e.status());
5151

52-
5352
execute(e.id(), e.data(), e.isDone());
5453
}
5554

@@ -62,17 +61,8 @@ public void execute(final long triggerId, final TriggerEntity data, boolean isDo
6261
completedTriggerRepository.save(state);
6362
}
6463

65-
var detail = new HistoryTriggerEntity();
66-
detail.setExecutionCount(data.getExecutionCount());
64+
var detail = HistoryTriggerEntity.from(data);
6765
detail.setInstanceId(triggerId);
68-
detail.setKey(data.getKey());
69-
70-
var msg = data.getExceptionName();
71-
if (data.getLastException() != null) msg = data.getLastException();
72-
detail.setMessage(StringUtils.substring(msg, 0, 200));
73-
74-
detail.setStart(data.getStart());
75-
detail.setStatus(data.getStatus());
76-
triggerHistoryDetailRepository.save(detail);
66+
historyTriggerRepository.save(detail);
7767
}
7868
}

core/src/main/java/org/sterl/spring/persistent_tasks/history/model/HistoryTriggerEntity.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.time.OffsetDateTime;
44

5+
import org.apache.commons.lang3.StringUtils;
56
import org.sterl.spring.persistent_tasks.api.TriggerKey;
67
import org.sterl.spring.persistent_tasks.api.TriggerStatus;
78
import org.sterl.spring.persistent_tasks.shared.model.TriggerEntity;
@@ -77,5 +78,20 @@ public class HistoryTriggerEntity {
7778

7879
@Column(length = 200, updatable = false)
7980
private String message;
81+
82+
83+
public static HistoryTriggerEntity from(TriggerEntity data) {
84+
var result = new HistoryTriggerEntity();
85+
result.setExecutionCount(data.getExecutionCount());
86+
result.setKey(data.getKey());
87+
88+
var msg = data.getExceptionName();
89+
if (data.getLastException() != null) msg = data.getLastException();
90+
result.setMessage(StringUtils.substring(msg, 0, 200));
91+
92+
result.setStart(data.getStart());
93+
result.setStatus(data.getStatus());
94+
return result;
95+
}
8096

8197
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import org.sterl.spring.persistent_tasks.api.TriggerStatus;
1313
import org.sterl.spring.persistent_tasks.history.model.HistoryTriggerEntity;
1414

15-
public interface TriggerHistoryDetailRepository
15+
public interface HistoryTriggerRepository
1616
extends JpaRepository<HistoryTriggerEntity, Long>, QuerydslPredicateExecutor<HistoryTriggerEntity> {
1717

1818
@Query("""
@@ -28,7 +28,7 @@ Page<HistoryTriggerEntity> findAllByInstanceId(
2828
WHERE e.createdTime < :age
2929
""")
3030
@Modifying
31-
long deleteOlderThan(@Param("age") OffsetDateTime age);
31+
int deleteOlderThan(@Param("age") OffsetDateTime age);
3232

3333
@Query("""
3434
SELECT COUNT(e.id)

core/src/main/java/org/sterl/spring/persistent_tasks/scheduler/SchedulerTimer.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ void rescheduleAbandonedTasks() {
4343
for (SchedulerService s : schedulerServices) {
4444
try {
4545
final var count = s.rescheduleAbandonedTriggers(timeout);
46-
log.info("Found {} abandoned tasks for {}. Timeout={}",
47-
count.size(), s.getName(), taskTimeout);
46+
if (count.size() > 0) {
47+
log.info("Found {} abandoned tasks for {}. Timeout={}",
48+
count.size(), s.getName(), taskTimeout);
49+
}
4850
} catch (Exception e) {
4951
log.error("Scheduler {} failed schedule abandoned tasks", s.getName(), e);
5052
}

core/src/main/java/org/sterl/spring/persistent_tasks/shared/repository/TriggerRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,5 @@ WHERE e.data.status IN ( :status )
133133
WHERE e.data.createdTime < :age
134134
""")
135135
@Modifying
136-
long deleteOlderThan(@Param("age") OffsetDateTime age);
136+
int deleteOlderThan(@Param("age") OffsetDateTime age);
137137
}

core/src/test/java/org/sterl/spring/persistent_tasks/history/HistoryServiceTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import java.time.OffsetDateTime;
66
import java.util.Optional;
7+
import java.util.Random;
78
import java.util.concurrent.TimeoutException;
89

910
import org.junit.jupiter.api.RepeatedTest;
@@ -16,13 +17,21 @@
1617
import org.sterl.spring.persistent_tasks.api.TriggerKey;
1718
import org.sterl.spring.persistent_tasks.api.TriggerRequest;
1819
import org.sterl.spring.persistent_tasks.api.TriggerStatus;
20+
import org.sterl.spring.persistent_tasks.history.component.TriggerHistoryComponent;
21+
import org.sterl.spring.persistent_tasks.shared.model.TriggerEntity;
22+
23+
import com.github.f4b6a3.uuid.UuidCreator;
1924

2025
class HistoryServiceTest extends AbstractSpringTest {
2126

27+
Random random = new Random();
2228
@Autowired
2329
private HistoryService subject;
2430
@Autowired
2531
private PersistentTaskService persistentTaskService;
32+
33+
@Autowired
34+
private TriggerHistoryComponent triggerHistory;
2635

2736
@Test
2837
void testReQueueTrigger() {
@@ -76,4 +85,43 @@ void testTriggerHistoryTrx() {
7685
hibernateAsserts.assertTrxCount(3);
7786
assertThat(subject.countTriggers(trigger)).isEqualTo(1);
7887
}
88+
89+
@Test
90+
void testTriggerDelete() {
91+
// GIVEN
92+
// WHEN
93+
subject.deleteAll();
94+
}
95+
96+
@Test
97+
void testDeleteByDate() {
98+
// GIVEN
99+
var now = OffsetDateTime.now();
100+
var task = UuidCreator.getTimeOrderedEpochFast().toString();
101+
var instanceId = random.nextLong(0, 99999) + now.toEpochSecond();
102+
103+
trx.executeWithoutResult(t -> {
104+
triggerHistory.execute(instanceId, TriggerEntity.builder()
105+
.key(new TriggerKey("123", task))
106+
.createdTime(now)
107+
.build(), true);
108+
109+
// this one we keep
110+
triggerHistory.execute(instanceId, TriggerEntity.builder()
111+
.key(new TriggerKey("123", task))
112+
.createdTime(now.plusMinutes(1))
113+
.build(), true);
114+
});
115+
116+
// WHEN
117+
var count = subject.deleteAllOlderThan(now.minusSeconds(1));
118+
119+
// THEN
120+
assertThat(count).isZero();
121+
122+
// WHEN
123+
count = subject.deleteAllOlderThan(now.plusSeconds(30));
124+
// THEN
125+
assertThat(count).isEqualTo(3);
126+
}
79127
}

core/src/test/java/org/sterl/spring/persistent_tasks/trigger/TriggerServiceTest.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -433,16 +433,19 @@ void testRescheduleAbandonedTasks() {
433433
void testRescheduleAbandonedTasksOnlyRunning() {
434434
// GIVEN
435435
var now = OffsetDateTime.now();
436-
var t1 = new RunningTriggerEntity(new TriggerKey(UuidCreator.getTimeOrdered().toString(), "fooTask"))
436+
var t1 = trx.execute(t -> {
437+
RunningTriggerEntity running = null;
438+
for (var status : TriggerStatus.values()) {
439+
var any = new RunningTriggerEntity(new TriggerKey(UuidCreator.getTimeOrdered().toString(), "fooTask"))
437440
.runOn("fooScheduler");
438-
t1.setLastPing(now.minusSeconds(60));
439-
triggerRepository.save(t1);
441+
any.getData().setStatus(status);
442+
any.setLastPing(now.minusSeconds(60));
443+
any = triggerRepository.save(any);
444+
if (status == TriggerStatus.RUNNING) running = any;
445+
}
446+
return running;
447+
});
440448

441-
var t2 = new RunningTriggerEntity(
442-
new TriggerKey(UuidCreator.getTimeOrdered().toString(), "barTask"));
443-
t2.setLastPing(now.minusSeconds(60));
444-
triggerRepository.save(t2);
445-
446449
// WHEN
447450
final var rescheduledTasks = subject.rescheduleAbandoned(now.minusSeconds(59));
448451

@@ -615,4 +618,10 @@ void testAwaitForSignalTriggersInTimeoutWillNotRun() {
615618
// AND
616619
asserts.assertMissing("old state");
617620
}
621+
622+
@Test
623+
void testDeleteAll() {
624+
// WHEN
625+
subject.deleteAll();
626+
}
618627
}

0 commit comments

Comments
 (0)