Skip to content

Commit 42ae0a1

Browse files
authored
Support pmw Adjust names (#14)
* using querydsl for the search * cleanup server api * implemented waiting triggers * timers can now be disabled * Resume added * added the ability to filter * adjusted entity names and table names * using old sequence names as rename doesn't work * using in test virtual thread factory * added wait for history insert * removed one test * enabled test again * added wait for history threads * using default thread factory again
1 parent e76f7d3 commit 42ae0a1

File tree

96 files changed

+1697
-857
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+1697
-857
lines changed

.github/workflows/build.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ jobs:
8080
services:
8181
postgres:
8282
image: postgres
83-
options: --name pg-container
8483
env:
8584
POSTGRES_USER: sa
8685
POSTGRES_PASSWORD: veryStrong123

RUN_AND_BUILD.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mvn versions:set -DnewVersion=1.6.0-SNAPSHOT -DgenerateBackupPoms=false
55

66
## postgres
77

8-
docker run --name pg-container -e POSTGRES_USER=sa -e POSTGRES_PASSWORD=veryStrong123 -p 5432:5432 -d postgres
8+
docker run -e POSTGRES_USER=sa -e POSTGRES_PASSWORD=veryStrong123 -p 5432:5432 -d postgres
99

1010
## azure-sql-edge
1111

core/pom.xml

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>org.sterl.spring</groupId>
88
<artifactId>spring-persistent-tasks-root</artifactId>
9-
<version>1.7.1-SNAPSHOT</version>
9+
<version>2.0.0-SNAPSHOT</version>
1010
<relativePath>../pom.xml</relativePath>
1111
</parent>
1212

@@ -25,6 +25,21 @@
2525
<groupId>org.springframework.boot</groupId>
2626
<artifactId>spring-boot-starter-data-jpa</artifactId>
2727
</dependency>
28+
29+
<dependency>
30+
<groupId>com.querydsl</groupId>
31+
<artifactId>querydsl-apt</artifactId>
32+
<version>${querydsl.version}</version>
33+
<classifier>jakarta</classifier>
34+
<scope>provided</scope>
35+
</dependency>
36+
<dependency>
37+
<groupId>com.querydsl</groupId>
38+
<artifactId>querydsl-jpa</artifactId>
39+
<version>${querydsl.version}</version>
40+
<classifier>jakarta</classifier>
41+
</dependency>
42+
2843
<dependency>
2944
<groupId>org.springframework.boot</groupId>
3045
<artifactId>spring-boot-starter-validation</artifactId>
@@ -38,6 +53,12 @@
3853
<artifactId>liquibase-core</artifactId>
3954
</dependency>
4055

56+
<dependency>
57+
<groupId>com.github.f4b6a3</groupId>
58+
<artifactId>uuid-creator</artifactId>
59+
<version>6.1.1</version>
60+
</dependency>
61+
4162
<dependency>
4263
<groupId>org.springframework.boot</groupId>
4364
<artifactId>spring-boot-devtools</artifactId>
@@ -52,11 +73,6 @@
5273
<scope>test</scope>
5374
</dependency>
5475

55-
<dependency>
56-
<groupId>org.liquibase</groupId>
57-
<artifactId>liquibase-core</artifactId>
58-
<scope>test</scope>
59-
</dependency>
6076
<dependency>
6177
<groupId>com.h2database</groupId>
6278
<artifactId>h2</artifactId>
@@ -186,12 +202,16 @@
186202
</customTypeMappings>
187203
<classes>
188204
<class>org.springframework.data.web.PagedModel</class>
189-
<class>
190-
org.sterl.spring.persistent_tasks.scheduler.entity.SchedulerEntity</class>
205+
<class>org.sterl.spring.persistent_tasks.scheduler.entity.SchedulerEntity</class>
191206
</classes>
192207
<classPatterns>
193-
<pattern>org.sterl.spring.persistent_tasks.api.**</pattern>
208+
<pattern>org.sterl.spring.persistent_tasks.api.*</pattern>
194209
</classPatterns>
210+
<excludeClasses>
211+
<class>java.lang.Class</class>
212+
<class>org.sterl.spring.persistent_tasks.api.QTriggerKey</class>
213+
<class>java.io.Serializable</class>
214+
</excludeClasses>
195215
<outputFile>../ui/src/server-api.d.ts</outputFile>
196216
<outputKind>module</outputKind>
197217
</configuration>

core/src/main/java/org/sterl/spring/persistent_tasks/PersistentTaskService.java

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,24 @@
77
import java.util.List;
88
import java.util.Optional;
99

10+
import org.apache.commons.lang3.StringUtils;
1011
import org.springframework.context.event.EventListener;
1112
import org.springframework.data.domain.PageRequest;
1213
import org.springframework.data.domain.Pageable;
13-
import org.springframework.data.domain.Sort;
1414
import org.springframework.data.domain.Sort.Direction;
1515
import org.springframework.lang.NonNull;
1616
import org.springframework.stereotype.Service;
1717
import org.springframework.transaction.annotation.Transactional;
18-
import org.sterl.spring.persistent_tasks.api.AddTriggerRequest;
1918
import org.sterl.spring.persistent_tasks.api.TriggerKey;
19+
import org.sterl.spring.persistent_tasks.api.TriggerRequest;
20+
import org.sterl.spring.persistent_tasks.api.TriggerSearch;
2021
import org.sterl.spring.persistent_tasks.api.event.TriggerTaskCommand;
2122
import org.sterl.spring.persistent_tasks.history.HistoryService;
22-
import org.sterl.spring.persistent_tasks.history.model.TriggerHistoryLastStateEntity;
23+
import org.sterl.spring.persistent_tasks.history.model.CompletedTriggerEntity;
2324
import org.sterl.spring.persistent_tasks.scheduler.SchedulerService;
24-
import org.sterl.spring.persistent_tasks.shared.model.TriggerData;
25+
import org.sterl.spring.persistent_tasks.shared.model.TriggerEntity;
2526
import org.sterl.spring.persistent_tasks.trigger.TriggerService;
26-
import org.sterl.spring.persistent_tasks.trigger.model.TriggerEntity;
27+
import org.sterl.spring.persistent_tasks.trigger.model.RunningTriggerEntity;
2728

2829
import lombok.RequiredArgsConstructor;
2930

@@ -40,14 +41,14 @@ public class PersistentTaskService {
4041
private final HistoryService historyService;
4142

4243
/**
43-
* Returns the last known {@link TriggerData} to a given key. First running triggers are checked.
44+
* Returns the last known {@link TriggerEntity} to a given key. First running triggers are checked.
4445
* Maybe out of the history event from a retry execution of the very same id.
4546
*
4647
* @param key the {@link TriggerKey} to look for
47-
* @return the {@link TriggerData} to the {@link TriggerKey}
48+
* @return the {@link TriggerEntity} to the {@link TriggerKey}
4849
*/
49-
public Optional<TriggerData> getLastTriggerData(TriggerKey key) {
50-
final Optional<TriggerEntity> trigger = triggerService.get(key);
50+
public Optional<TriggerEntity> getLastTriggerData(TriggerKey key) {
51+
final Optional<RunningTriggerEntity> trigger = triggerService.get(key);
5152
if (trigger.isEmpty()) {
5253
var history = historyService.findLastKnownStatus(key);
5354
if (history.isPresent()) {
@@ -59,7 +60,7 @@ public Optional<TriggerData> getLastTriggerData(TriggerKey key) {
5960
}
6061
}
6162

62-
public Optional<TriggerData> getLastDetailData(TriggerKey key) {
63+
public Optional<TriggerEntity> getLastDetailData(TriggerKey key) {
6364
var data = historyService.findAllDetailsForKey(key, Pageable.ofSize(1));
6465
if (data.isEmpty()) {
6566
return Optional.empty();
@@ -85,14 +86,14 @@ void queue(TriggerTaskCommand<? extends Serializable> event) {
8586
*/
8687
@Transactional(timeout = 10)
8788
@NonNull
88-
public <T extends Serializable> List<TriggerKey> queue(Collection<AddTriggerRequest<T>> triggers) {
89+
public <T extends Serializable> List<TriggerKey> queue(Collection<TriggerRequest<T>> triggers) {
8990
if (triggers == null || triggers.isEmpty()) {
9091
return Collections.emptyList();
9192
}
9293

9394
return triggers.stream() //
9495
.map(t -> triggerService.queue(t)) //
95-
.map(TriggerEntity::getKey) //
96+
.map(RunningTriggerEntity::getKey) //
9697
.toList();
9798
}
9899
/**
@@ -104,7 +105,7 @@ public <T extends Serializable> List<TriggerKey> queue(Collection<AddTriggerRequ
104105
*/
105106
@Transactional(timeout = 5)
106107
@NonNull
107-
public <T extends Serializable> TriggerKey queue(AddTriggerRequest<T> trigger) {
108+
public <T extends Serializable> TriggerKey queue(TriggerRequest<T> trigger) {
108109
return triggerService.queue(trigger).getKey();
109110
}
110111

@@ -114,7 +115,7 @@ public <T extends Serializable> TriggerKey queue(AddTriggerRequest<T> trigger) {
114115
* @return the reference to the {@link TriggerKey}
115116
*/
116117
public <T extends Serializable> TriggerKey runOrQueue(
117-
AddTriggerRequest<T> triggerRequest) {
118+
TriggerRequest<T> triggerRequest) {
118119
if (schedulerService.isPresent()) {
119120
schedulerService.get().runOrQueue(triggerRequest);
120121
} else {
@@ -128,42 +129,41 @@ public <T extends Serializable> TriggerKey runOrQueue(
128129
* Data is limited to overall 300 elements.
129130
*
130131
* @param correlationId the id to search for
131-
* @return the found {@link TriggerData} sorted by create time ASC
132+
* @return the found {@link TriggerEntity} sorted by create time ASC
132133
*/
133134
@Transactional(readOnly = true, timeout = 5)
134-
public List<TriggerData> findAllTriggerByCorrelationId(String correlationId) {
135+
public List<TriggerEntity> findAllTriggerByCorrelationId(String correlationId) {
136+
if (StringUtils.isAllBlank(correlationId)) return Collections.emptyList();
137+
138+
final var search = TriggerSearch.byCorrelationId(correlationId);
135139

136-
var running = triggerService.findTriggerByCorrelationId(correlationId, Pageable.ofSize(100))
137-
.stream().map(TriggerEntity::getData)
140+
final var running = triggerService.searchTriggers(search, PageRequest.of(0, 100, TriggerSearch.DEFAULT_SORT))
141+
.stream().map(RunningTriggerEntity::getData)
138142
.toList();
139143

140-
var done = historyService.findTriggerByCorrelationId(correlationId, Pageable.ofSize(200))
141-
.stream().map(TriggerHistoryLastStateEntity::getData)
144+
final var done = historyService.searchTriggers(search, PageRequest.of(0, 200, TriggerSearch.DEFAULT_SORT))
145+
.stream().map(CompletedTriggerEntity::getData)
142146
.toList();
143147

144-
var result = new ArrayList<TriggerData>(running.size() + done.size());
148+
final var result = new ArrayList<TriggerEntity>(running.size() + done.size());
145149
result.addAll(done);
146150
result.addAll(running);
147151
return result;
148152
}
149-
150-
/**
151-
* Returns the first info to a trigger based on the correlationId.
152-
*
153-
* @param correlationId the id to search for
154-
* @return the found {@link TriggerData}
155-
*/
153+
156154
@Transactional(readOnly = true, timeout = 5)
157-
public Optional<TriggerData> findLastTriggerByCorrelationId(String correlationId) {
158-
final var page = PageRequest.of(0, 1, Sort.by(Direction.DESC, "data.createdTime"));
159-
var result = triggerService.findTriggerByCorrelationId(correlationId, page)
160-
.stream().map(TriggerEntity::getData)
161-
.toList();
155+
public Optional<TriggerEntity> findLastTriggerByCorrelationId(String correlationId) {
156+
final var page = PageRequest.of(0, 1, TriggerSearch.sortByCreatedTime(Direction.DESC));
157+
final var search = TriggerSearch.byCorrelationId(correlationId);
158+
159+
var result = triggerService.searchTriggers(search, page)
160+
.stream().map(RunningTriggerEntity::getData)
161+
.toList();
162162

163163
if (result.isEmpty()) {
164-
result = historyService.findTriggerByCorrelationId(correlationId, page)
165-
.stream().map(TriggerHistoryLastStateEntity::getData)
166-
.toList();
164+
result = historyService.searchTriggers(search, page)
165+
.stream().map(CompletedTriggerEntity::getData)
166+
.toList();
167167
}
168168
return result.isEmpty() ? Optional.empty() : Optional.of(result.getFirst());
169169
}

core/src/main/java/org/sterl/spring/persistent_tasks/api/TaskId.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public TriggerBuilder<T> newTrigger(T state) {
2020
return new TriggerBuilder<>(this).state(state);
2121
}
2222

23-
public AddTriggerRequest<T> newUniqueTrigger(T state) {
23+
public TriggerRequest<T> newUniqueTrigger(T state) {
2424
return new TriggerBuilder<>(this).state(state).build();
2525
}
2626

@@ -34,19 +34,24 @@ public static class TriggerBuilder<T extends Serializable> {
3434
private final TaskId<T> taskId;
3535
private String id;
3636
private String correlationId;
37+
private String tag;
38+
private TriggerStatus status = TriggerStatus.WAITING;
3739
private T state;
3840
private OffsetDateTime when = OffsetDateTime.now();
39-
private int priority = AddTriggerRequest.DEFAULT_PRIORITY;
41+
private int priority = TriggerRequest.DEFAULT_PRIORITY;
4042

4143
public static <T extends Serializable> TriggerBuilder<T> newTrigger(String name) {
4244
return new TriggerBuilder<>(new TaskId<T>(name));
4345
}
4446
public static <T extends Serializable> TriggerBuilder<T> newTrigger(String name, T state) {
4547
return new TriggerBuilder<>(new TaskId<T>(name)).state(state);
4648
}
47-
public AddTriggerRequest<T> build() {
49+
public static <T extends Serializable> TriggerBuilder<T> newTrigger(TriggerKey key, T state) {
50+
return new TriggerBuilder<>(new TaskId<T>(key.getTaskName())).id(key.getId()).state(state);
51+
}
52+
public TriggerRequest<T> build() {
4853
var key = TriggerKey.of(id, taskId);
49-
return new AddTriggerRequest<>(key, state, when, priority, correlationId);
54+
return new TriggerRequest<>(key, status, state, when, priority, correlationId, tag);
5055
}
5156
/**
5257
* The ID of this task, same queued ids are replaced.
@@ -63,6 +68,10 @@ public TriggerBuilder<T> correlationId(String correlationId) {
6368
this.correlationId = correlationId;
6469
return this;
6570
}
71+
public TriggerBuilder<T> tag(String tag) {
72+
this.tag = tag;
73+
return this;
74+
}
6675
public TriggerBuilder<T> state(T state) {
6776
this.state = state;
6877
return this;
@@ -86,11 +95,24 @@ public TriggerBuilder<T> when(OffsetDateTime when) {
8695
}
8796
public TriggerBuilder<T> runAt(OffsetDateTime when) {
8897
this.when = when;
98+
this.status = TriggerStatus.WAITING;
8999
return this;
90100
}
101+
/**
102+
* synonym for {@link #runAt(OffsetDateTime)}
103+
*/
91104
public TriggerBuilder<T> runAfter(Duration duration) {
92105
runAt(OffsetDateTime.now().plus(duration));
93106
return this;
94107
}
108+
/**
109+
* Creates a trigger which waits for an external signal and
110+
* will run into {@link TriggerStatus#EXPIRED_SIGNAL} if no signal happens.
111+
*/
112+
public TriggerBuilder<T> waitForSignal(OffsetDateTime timeout) {
113+
this.when = timeout;
114+
this.status = TriggerStatus.AWAITING_SIGNAL;
115+
return this;
116+
}
95117
}
96118
}

core/src/main/java/org/sterl/spring/persistent_tasks/api/Trigger.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public class Trigger {
1515
/** the business key which is unique it is combination for triggers but not the history! */
1616
private TriggerKey key;
1717

18+
private String tag;
19+
1820
private String correlationId;
1921

2022
private String runningOn;

core/src/main/java/org/sterl/spring/persistent_tasks/api/TriggerKey.java

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

33
import java.io.Serializable;
44
import java.time.OffsetDateTime;
5-
import java.util.UUID;
65

76
import org.springframework.lang.Nullable;
87

@@ -29,7 +28,7 @@ public class TriggerKey implements Serializable {
2928
private String taskName;
3029

3130
public static TriggerKey of(@Nullable String id, TaskId<? extends Serializable> taskId) {
32-
return new TriggerKey(id == null ? UUID.randomUUID().toString() : id, taskId.name());
31+
return new TriggerKey(id, taskId.name());
3332
}
3433

3534
public TaskId<Serializable> toTaskId() {
@@ -40,30 +39,29 @@ public TaskId<Serializable> toTaskId() {
4039
* Builds a trigger for the given persistentTask name
4140
*/
4241
public TriggerKey(String taskName) {
43-
id = UUID.randomUUID().toString();
4442
this.taskName = taskName;
4543
}
4644

4745
/**
4846
* Just triggers the given persistentTask to be executed using <code>null</code> as state.
4947
*/
50-
public <T extends Serializable> AddTriggerRequest<T> newTrigger(TaskId<T> taskId) {
48+
public <T extends Serializable> TriggerRequest<T> newTrigger(TaskId<T> taskId) {
5149
return newTrigger(taskId, null);
5250
}
5351

54-
public <T extends Serializable> AddTriggerRequest<T> newTrigger(TaskId<T> taskId, T state) {
55-
return newTrigger(UUID.randomUUID().toString(), taskId, state);
52+
public <T extends Serializable> TriggerRequest<T> newTrigger(TaskId<T> taskId, T state) {
53+
return newTrigger(null, taskId, state);
5654
}
5755

58-
public <T extends Serializable> AddTriggerRequest<T> newTrigger(String id, TaskId<T> taskId, T state) {
56+
public <T extends Serializable> TriggerRequest<T> newTrigger(String id, TaskId<T> taskId, T state) {
5957
return newTrigger(id, taskId, state, OffsetDateTime.now());
6058
}
6159

62-
public <T extends Serializable> AddTriggerRequest<T> newTrigger(String id, TaskId<T> taskId, T state, OffsetDateTime when) {
60+
public <T extends Serializable> TriggerRequest<T> newTrigger(String id, TaskId<T> taskId, T state, OffsetDateTime when) {
6361
return taskId.newTrigger() //
6462
.id(id) //
6563
.state(state) //
6664
.when(when) //
67-
.build();
65+
.build(); //
6866
}
6967
}

0 commit comments

Comments
 (0)