Skip to content

Commit f70458e

Browse files
committed
adjusted history writing
1 parent 628e83d commit f70458e

File tree

13 files changed

+117
-63
lines changed

13 files changed

+117
-63
lines changed

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

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.springframework.data.domain.Page;
88
import org.springframework.data.domain.PageRequest;
99
import org.springframework.data.domain.Pageable;
10+
import org.springframework.data.domain.Sort;
1011
import org.springframework.data.domain.Sort.Direction;
1112
import org.sterl.spring.persistent_tasks.api.TriggerKey;
1213
import org.sterl.spring.persistent_tasks.history.model.TriggerHistoryDetailEntity;
@@ -23,18 +24,18 @@
2324
@TransactionalService
2425
@RequiredArgsConstructor
2526
public class HistoryService {
26-
private final TriggerHistoryDetailRepository triggerHistoryDetailRepository;
2727
private final TriggerHistoryLastStateRepository triggerHistoryLastStateRepository;
28+
private final TriggerHistoryDetailRepository triggerHistoryDetailRepository;
2829
private final TriggerService triggerService;
2930

3031
public Optional<TriggerHistoryLastStateEntity> findStatus(long triggerId) {
31-
return triggerHistoryDetailRepository.findById(triggerId);
32+
return triggerHistoryLastStateRepository.findById(triggerId);
3233
}
3334

3435
public Optional<TriggerHistoryLastStateEntity> findLastKnownStatus(TriggerKey triggerKey) {
35-
PageRequest page = PageRequest.of(0, 1).withSort(Direction.DESC, "e.data.createdTime", "id");
36-
var result = triggerHistoryDetailRepository.listKnownStatusFor(triggerKey, page);
37-
return result.isEmpty() ? Optional.empty() : Optional.of(result.get(0));
36+
final var page = PageRequest.of(0, 1).withSort(Direction.DESC, "data.createdTime", "id");
37+
final var result = triggerHistoryLastStateRepository.listKnownStatusFor(triggerKey, page);
38+
return result.isEmpty() ? Optional.empty() : Optional.of(result.getContent().get(0));
3839
}
3940

4041
public void deleteAll() {
@@ -54,14 +55,22 @@ public long countTriggers(TriggerStatus status) {
5455
return triggerHistoryDetailRepository.countByStatus(status);
5556
}
5657

57-
public List<TriggerHistoryDetailEntity> findAllForInstance(long instanceId) {
58-
return triggerHistoryLastStateRepository.findAllByInstanceId(instanceId);
58+
public List<TriggerHistoryDetailEntity> findAllDetailsForInstance(long instanceId) {
59+
return triggerHistoryDetailRepository.findAllByInstanceId(instanceId);
60+
}
61+
62+
public Page<TriggerHistoryDetailEntity> findAllDetailsForKey(TriggerKey key) {
63+
return findAllDetailsForKey(key, PageRequest.of(0, 100));
64+
}
65+
public Page<TriggerHistoryDetailEntity> findAllDetailsForKey(TriggerKey key, Pageable page) {
66+
page = sortByIdIfNeeded(page);
67+
return triggerHistoryDetailRepository.listKnownStatusFor(key, page);
5968
}
6069

6170
public Optional<TriggerEntity> reQueue(Long id, OffsetDateTime runAt) {
62-
final var lastState = triggerHistoryDetailRepository.findById(id);
71+
final var lastState = triggerHistoryLastStateRepository.findById(id);
6372
if (lastState.isEmpty()) return Optional.empty();
64-
73+
6574
final var data = lastState.get().getData();
6675
final var trigger = lastState.get().newTaskId().newTrigger()
6776
.state(data.getState())
@@ -74,19 +83,29 @@ public Optional<TriggerEntity> reQueue(Long id, OffsetDateTime runAt) {
7483
}
7584

7685
public long countTriggers(TriggerKey key) {
77-
return triggerHistoryDetailRepository.countByKey(key);
86+
return triggerHistoryLastStateRepository.countByKey(key);
7887
}
7988

8089
public Page<TriggerHistoryLastStateEntity> findTriggerState(
8190
TriggerKey key, Pageable page) {
82-
if (key == null) return triggerHistoryDetailRepository.findAll(page);
83-
if (key.getId() == null && key.getTaskName() == null) return triggerHistoryDetailRepository.findAll(page);
91+
92+
page = sortByIdIfNeeded(page);
93+
if (key == null) return triggerHistoryLastStateRepository.findAll(page);
94+
if (key.getId() == null && key.getTaskName() == null) return triggerHistoryLastStateRepository.findAll(page);
8495
if (key.getId() == null && key.getTaskName() != null) {
85-
return triggerHistoryDetailRepository.findAll(key.getTaskName(), page);
96+
return triggerHistoryLastStateRepository.findAll(key.getTaskName(), page);
8697
}
87-
return triggerHistoryDetailRepository.findAll(
98+
return triggerHistoryLastStateRepository.findAll(
8899
key.getId(),
89100
key.getTaskName(),
90101
page);
91102
}
103+
104+
private Pageable sortByIdIfNeeded(Pageable page) {
105+
if (page.getSort() == Sort.unsorted()) {
106+
return PageRequest.of(page.getPageNumber(), page.getPageSize(),
107+
Sort.by(Direction.DESC, "id"));
108+
}
109+
return page;
110+
}
92111
}

core/src/main/java/org/sterl/spring/persistent_tasks/history/api/TriggerHistoryResource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class TriggerHistoryResource {
3030
@GetMapping("history/instance/{instanceId}")
3131
public List<Trigger> listInstances(@PathVariable("instanceId") long instanceId) {
3232
return FromTriggerStateDetailEntity.INSTANCE.convert( //
33-
historyService.findAllForInstance(instanceId));
33+
historyService.findAllDetailsForInstance(instanceId));
3434
}
3535

3636
@GetMapping("history")

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

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

33
import java.time.OffsetDateTime;
44

5-
import org.springframework.transaction.event.TransactionPhase;
6-
import org.springframework.transaction.event.TransactionalEventListener;
5+
import org.springframework.context.event.EventListener;
6+
import org.springframework.transaction.annotation.Transactional;
77
import org.sterl.spring.persistent_tasks.history.model.TriggerHistoryDetailEntity;
88
import org.sterl.spring.persistent_tasks.history.model.TriggerHistoryLastStateEntity;
99
import org.sterl.spring.persistent_tasks.history.repository.TriggerHistoryDetailRepository;
@@ -18,25 +18,26 @@
1818
@RequiredArgsConstructor
1919
public class TriggerHistoryComponent {
2020

21-
private final TriggerHistoryDetailRepository triggerHistoryDetailRepository;
2221
private final TriggerHistoryLastStateRepository triggerHistoryLastStateRepository;
22+
private final TriggerHistoryDetailRepository triggerHistoryDetailRepository;
2323

2424
public void write(TriggerEntity e) {
2525
var state = new TriggerHistoryLastStateEntity();
2626
state.setId(e.getId());
2727
state.setData(e.getData().toBuilder().build());
28-
triggerHistoryDetailRepository.save(state);
28+
triggerHistoryLastStateRepository.save(state);
2929

3030
var detail = new TriggerHistoryDetailEntity();
3131
detail.setInstanceId(e.getId());
3232
detail.setData(e.getData().toBuilder()
3333
.state(null)
3434
.build());
3535
detail.getData().setCreatedTime(OffsetDateTime.now());
36-
triggerHistoryLastStateRepository.save(detail);
36+
triggerHistoryDetailRepository.save(detail);
3737
}
3838

39-
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
39+
@Transactional
40+
@EventListener
4041
public void onPersistentTaskEvent(TriggerLifeCycleEvent triggerLifeCycleEvent) {
4142
write(triggerLifeCycleEvent.trigger());
4243
}

core/src/main/java/org/sterl/spring/persistent_tasks/history/repository/HistoryTriggerRepository.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.sterl.spring.persistent_tasks.history.repository;
22

3-
import java.util.List;
4-
3+
import org.springframework.data.domain.Page;
54
import org.springframework.data.domain.Pageable;
65
import org.springframework.data.jpa.repository.Query;
76
import org.springframework.data.repository.NoRepositoryBean;
@@ -17,5 +16,5 @@ public interface HistoryTriggerRepository<T extends HasTriggerData> extends Trig
1716
SELECT e FROM #{#entityName} e
1817
WHERE e.data.key = :key
1918
""")
20-
List<T> listKnownStatusFor(@Param("key") TriggerKey key, Pageable page);
19+
Page<T> listKnownStatusFor(@Param("key") TriggerKey key, Pageable page);
2120
}
Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,40 @@
11
package org.sterl.spring.persistent_tasks.history.repository;
22

3-
import org.sterl.spring.persistent_tasks.history.model.TriggerHistoryLastStateEntity;
3+
import java.util.List;
44

5-
public interface TriggerHistoryDetailRepository extends HistoryTriggerRepository<TriggerHistoryLastStateEntity> {
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
7+
import org.springframework.data.jpa.repository.Query;
8+
import org.springframework.data.repository.query.Param;
9+
import org.sterl.spring.persistent_tasks.api.HistoryOverview;
10+
import org.sterl.spring.persistent_tasks.history.model.TriggerHistoryDetailEntity;
611

12+
public interface TriggerHistoryDetailRepository extends HistoryTriggerRepository<TriggerHistoryDetailEntity> {
13+
14+
@Query("""
15+
SELECT new org.sterl.spring.persistent_tasks.api.HistoryOverview(
16+
e.instanceId,
17+
e.data.key.taskName,
18+
count(1) as entryCount,
19+
MIN(e.data.start) as start,
20+
MAX(e.data.end) as end,
21+
MIN(e.data.createdTime) as createdTime,
22+
MAX(e.data.executionCount) as executionCount,
23+
AVG(e.data.runningDurationInMs) as runningDurationInMs
24+
)
25+
FROM #{#entityName} e
26+
GROUP BY
27+
e.instanceId,
28+
e.data.key.taskName
29+
ORDER BY end DESC, createdTime DESC
30+
""")
31+
Page<HistoryOverview> listHistoryOverview(Pageable page);
32+
33+
@Query("""
34+
SELECT e
35+
FROM #{#entityName} e
36+
WHERE e.instanceId = :instanceId
37+
ORDER BY e.id DESC
38+
""")
39+
List<TriggerHistoryDetailEntity> findAllByInstanceId(@Param("instanceId") long instanceId);
740
}

core/src/main/java/org/sterl/spring/persistent_tasks/history/repository/TriggerHistoryLastStateRepository.java

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,9 @@
88
import org.springframework.data.repository.query.Param;
99
import org.sterl.spring.persistent_tasks.api.HistoryOverview;
1010
import org.sterl.spring.persistent_tasks.history.model.TriggerHistoryDetailEntity;
11+
import org.sterl.spring.persistent_tasks.history.model.TriggerHistoryLastStateEntity;
1112

12-
public interface TriggerHistoryLastStateRepository extends HistoryTriggerRepository<TriggerHistoryDetailEntity> {
13+
public interface TriggerHistoryLastStateRepository extends HistoryTriggerRepository<TriggerHistoryLastStateEntity> {
1314

14-
@Query("""
15-
SELECT new org.sterl.spring.persistent_tasks.api.HistoryOverview(
16-
e.instanceId,
17-
e.data.key.taskName,
18-
count(1) as entryCount,
19-
MIN(e.data.start) as start,
20-
MAX(e.data.end) as end,
21-
MIN(e.data.createdTime) as createdTime,
22-
MAX(e.data.executionCount) as executionCount,
23-
AVG(e.data.runningDurationInMs) as runningDurationInMs
24-
)
25-
FROM #{#entityName} e
26-
GROUP BY
27-
e.instanceId,
28-
e.data.key.taskName
29-
ORDER BY end DESC, createdTime DESC
30-
""")
31-
Page<HistoryOverview> listHistoryOverview(Pageable page);
32-
33-
@Query("""
34-
SELECT e
35-
FROM #{#entityName} e
36-
WHERE e.instanceId = :instanceId
37-
ORDER BY e.data.createdTime ASC
38-
""")
39-
List<TriggerHistoryDetailEntity> findAllByInstanceId(@Param("instanceId") long instanceId);
15+
4016
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ SELECT COUNT(e.data.key)
4343
long countByKey(@Param("key") TriggerKey key);
4444

4545
@Query("""
46-
SELECT COUNT(e.data.key)
46+
SELECT COUNT(e.id)
4747
FROM #{#entityName} e
4848
WHERE e.data.status = :status
4949
""")
5050
long countByStatus(@Param("status") TriggerStatus status);
5151

5252
@Query("""
53-
SELECT COUNT(e.data.key)
53+
SELECT COUNT(e.id)
5454
FROM #{#entityName} e
5555
WHERE e.data.status IN ( :status )
5656
""")

core/src/main/java/org/sterl/spring/persistent_tasks/trigger/component/ReadTriggerComponent.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
@RequiredArgsConstructor
2323
public class ReadTriggerComponent {
2424
private final TriggerRepository triggerRepository;
25-
2625

2726
public long countByTaskName(@NotNull String name) {
2827
return triggerRepository.countByTaskName(name);

core/src/test/java/org/sterl/spring/persistent_tasks/AbstractSpringTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ protected Optional<TriggerEntity> runNextTrigger() {
165165

166166
protected void awaitRunningTasks() throws TimeoutException, InterruptedException {
167167
final long start = System.currentTimeMillis();
168-
if (triggerService.countTriggers(TriggerStatus.RUNNING) > 0) {
168+
while (triggerService.countTriggers(TriggerStatus.RUNNING) > 0) {
169169
if (System.currentTimeMillis() - start > 2000) {
170170
throw new TimeoutException("Still running after 2s");
171171
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44

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

89
import org.junit.jupiter.api.Test;
910
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.data.domain.PageRequest;
1012
import org.sterl.spring.persistent_tasks.AbstractSpringTest;
1113
import org.sterl.spring.persistent_tasks.AbstractSpringTest.TaskConfig.Task3;
1214
import org.sterl.spring.persistent_tasks.api.AddTriggerRequest;
15+
import org.sterl.spring.persistent_tasks.shared.model.TriggerStatus;
1316
import org.sterl.spring.persistent_tasks.trigger.model.TriggerEntity;
1417

1518
class HistoryServiceTest extends AbstractSpringTest {
@@ -35,4 +38,20 @@ void testReQueueTrigger() {
3538
// AND
3639
assertThat(subject.countTriggers(trigger.getKey())).isEqualTo(2);
3740
}
41+
42+
@Test
43+
void testTriggerHistory() throws TimeoutException, InterruptedException {
44+
// GIVEN
45+
final var trigger = Task3.ID.newUniqueTrigger("Hallo");
46+
triggerService.queue(trigger);
47+
persistentTaskService.executeTriggersAndWait();
48+
// WHEN
49+
var triggers = subject.findAllDetailsForKey(trigger.key(), PageRequest.of(0, 100)).getContent();
50+
51+
// AND
52+
assertThat(triggers).hasSize(3);
53+
assertThat(triggers.get(0).getData().getStatus()).isEqualTo(TriggerStatus.SUCCESS);
54+
assertThat(triggers.get(1).getData().getStatus()).isEqualTo(TriggerStatus.RUNNING);
55+
assertThat(triggers.get(2).getData().getStatus()).isEqualTo(TriggerStatus.WAITING);
56+
}
3857
}

0 commit comments

Comments
 (0)