Skip to content

Commit a20614d

Browse files
imDMKgemini-code-assist[bot]igoyekRollcziJakubk15
authored
GH-1153 Rework delay system with per-entry Instant TTL (#1184)
* delay API: rework delay system with per-entry Instant TTL * Follow GEMINI code review * Update eternalcore-api/src/main/java/com/eternalcode/core/delay/GuavaDelay.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update eternalcore-api/src/main/java/com/eternalcode/core/delay/GuavaDelay.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update eternalcore-api/src/main/java/com/eternalcode/core/delay/Delay.java Co-authored-by: Igor Michalski <[email protected]> * review * Added Javadocs and introduced configurable maximumSize value. * Follow Rollczi review suggestions. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Igor Michalski <[email protected]> Co-authored-by: Rollczi <[email protected]> Co-authored-by: Jakub Kędziora <[email protected]>
1 parent 5235ca5 commit a20614d

File tree

10 files changed

+240
-66
lines changed

10 files changed

+240
-66
lines changed

buildSrc/src/main/kotlin/Versions.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@ object Versions {
4949
// tests
5050
const val JUNIT_BOM = "6.0.1"
5151
const val MOCKITO_CORE = "5.21.0"
52-
52+
const val ASSERTJ_CORE = "3.26.3"
53+
const val AWAITILITY = "4.2.1"
5354
}

eternalcore-api/src/main/java/com/eternalcode/core/delay/Delay.java

Lines changed: 0 additions & 50 deletions
This file was deleted.

eternalcore-core/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ dependencies {
2525
annotationProcessor("org.projectlombok:lombok:${Versions.LOMBOK}")
2626

2727
testImplementation("com.eternalcode:eternalcode-commons-bukkit:${Versions.ETERNALCODE_COMMONS}")
28+
testImplementation("org.assertj:assertj-core:${Versions.ASSERTJ_CORE}")
29+
testImplementation("org.awaitility:awaitility:${Versions.AWAITILITY}")
2830
}
2931

3032
eternalShadow {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.eternalcode.core.delay;
2+
3+
import com.github.benmanes.caffeine.cache.Cache;
4+
import com.github.benmanes.caffeine.cache.Caffeine;
5+
6+
import java.time.Duration;
7+
import java.time.Instant;
8+
import java.util.function.Supplier;
9+
10+
public class Delay<T> {
11+
12+
private final Cache<T, Instant> cache;
13+
private final Supplier<Duration> defaultDelay;
14+
15+
private Delay(Supplier<Duration> defaultDelay) {
16+
if (defaultDelay == null) {
17+
throw new IllegalArgumentException("defaultDelay cannot be null");
18+
}
19+
20+
this.defaultDelay = defaultDelay;
21+
this.cache = Caffeine.newBuilder()
22+
.expireAfter(new InstantExpiry<T>())
23+
.build();
24+
}
25+
26+
public void markDelay(T key, Duration delay) {
27+
if (delay.isZero() || delay.isNegative()) {
28+
this.cache.invalidate(key);
29+
}
30+
31+
this.cache.put(key, Instant.now().plus(delay));
32+
}
33+
public void markDelay(T key) {
34+
this.markDelay(key, this.defaultDelay.get());
35+
}
36+
37+
public void unmarkDelay(T key) {
38+
this.cache.invalidate(key);
39+
}
40+
41+
public boolean hasDelay(T key) {
42+
Instant delayExpireMoment = this.getExpireAt(key);
43+
return Instant.now().isBefore(delayExpireMoment);
44+
}
45+
46+
public Duration getRemaining(T key) {
47+
return Duration.between(Instant.now(), this.getExpireAt(key));
48+
}
49+
50+
private Instant getExpireAt(T key) {
51+
return this.cache.asMap().getOrDefault(key, Instant.MIN);
52+
}
53+
54+
public static <T> Delay<T> withDefault(Supplier<Duration> defaultDelay) {
55+
return new Delay<>(defaultDelay);
56+
}
57+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.eternalcode.core.delay;
2+
3+
import com.github.benmanes.caffeine.cache.Expiry;
4+
import java.time.Duration;
5+
import java.time.Instant;
6+
import org.jetbrains.annotations.NotNull;
7+
8+
class InstantExpiry<T> implements Expiry<@NotNull T, @NotNull Instant> {
9+
10+
@Override
11+
public long expireAfterCreate(@NotNull T key, @NotNull Instant expireTime, long currentTime) {
12+
return timeToExpire(expireTime);
13+
}
14+
15+
@Override
16+
public long expireAfterUpdate(@NotNull T key, @NotNull Instant newExpireTime, long currentTime, long currentDuration) {
17+
return timeToExpire(newExpireTime);
18+
}
19+
20+
@Override
21+
public long expireAfterRead(@NotNull T key, @NotNull Instant value, long currentTime, long currentDuration) {
22+
return currentDuration;
23+
}
24+
25+
private static long timeToExpire(Instant expireTime) {
26+
Duration toExpire = Duration.between(Instant.now(), expireTime);
27+
if (toExpire.isNegative()) {
28+
return 0;
29+
}
30+
31+
long nanos = toExpire.toNanos();
32+
if (nanos == 0) {
33+
return 1;
34+
}
35+
36+
return nanos;
37+
}
38+
39+
}

eternalcore-core/src/main/java/com/eternalcode/core/feature/afk/AfkCommand.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class AfkCommand {
3737
this.noticeService = noticeService;
3838
this.afkSettings = afkSettings;
3939
this.afkService = afkService;
40-
this.delay = new Delay<>(() -> this.afkSettings.afkCommandDelay());
40+
this.delay = Delay.withDefault(() -> this.afkSettings.afkCommandDelay());
4141
}
4242

4343
@Execute
@@ -51,7 +51,7 @@ void execute(@Sender Player player) {
5151
}
5252

5353
if (this.delay.hasDelay(uuid)) {
54-
Duration time = this.delay.getDurationToExpire(uuid);
54+
Duration time = this.delay.getRemaining(uuid);
5555

5656
this.noticeService
5757
.create()
@@ -64,6 +64,6 @@ void execute(@Sender Player player) {
6464
}
6565

6666
this.afkService.switchAfk(uuid, AfkReason.COMMAND);
67-
this.delay.markDelay(uuid, this.afkSettings.afkCommandDelay());
67+
this.delay.markDelay(uuid);
6868
}
6969
}

eternalcore-core/src/main/java/com/eternalcode/core/feature/helpop/HelpOpCommand.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class HelpOpCommand {
4242
this.helpOpSettings = helpOpSettings;
4343
this.eventCaller = eventCaller;
4444
this.server = server;
45-
this.delay = new Delay<>(() -> this.helpOpSettings.helpOpDelay());
45+
this.delay = Delay.withDefault(() -> this.helpOpSettings.helpOpDelay());
4646
}
4747

4848
@Execute
@@ -58,7 +58,7 @@ void execute(@Sender Player player, @Join String message) {
5858
}
5959

6060
if (this.delay.hasDelay(uuid)) {
61-
Duration time = this.delay.getDurationToExpire(uuid);
61+
Duration time = this.delay.getRemaining(uuid);
6262

6363
this.noticeService.create()
6464
.notice(translation -> translation.helpOp().helpOpDelay())
@@ -91,7 +91,7 @@ void execute(@Sender Player player, @Join String message) {
9191
.notice(translation -> translation.helpOp().send())
9292
.send();
9393

94-
this.delay.markDelay(uuid, this.helpOpSettings.helpOpDelay());
94+
this.delay.markDelay(uuid);
9595
}
9696

9797
}

eternalcore-core/src/main/java/com/eternalcode/core/feature/randomteleport/RandomTeleportCommand.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class RandomTeleportCommand {
4040
this.randomTeleportService = randomTeleportService;
4141
this.randomTeleportTaskService = randomTeleportTaskService;
4242
this.randomTeleportSettings = randomTeleportSettings;
43-
this.cooldown = new Delay<>(() -> this.randomTeleportSettings.cooldown());
43+
this.cooldown = Delay.withDefault(() -> this.randomTeleportSettings.cooldown());
4444
}
4545

4646
@Execute
@@ -68,7 +68,7 @@ void executeSelf(@Sender Player player) {
6868
this.handleTeleportSuccess(player);
6969
});
7070

71-
this.cooldown.markDelay(uuid, this.randomTeleportSettings.cooldown());
71+
this.cooldown.markDelay(uuid);
7272
}
7373

7474
@Execute
@@ -96,7 +96,7 @@ void executeOther(@Sender Viewer sender, @Arg Player player) {
9696
this.handleAdminTeleport(sender, player);
9797
});
9898

99-
this.cooldown.markDelay(uuid, this.randomTeleportSettings.cooldown());
99+
this.cooldown.markDelay(uuid);
100100
}
101101

102102
private void handleTeleportSuccess(Player player) {
@@ -129,7 +129,7 @@ private boolean hasRandomTeleportDelay(Player player) {
129129
}
130130

131131
if (this.cooldown.hasDelay(uniqueId)) {
132-
Duration time = this.cooldown.getDurationToExpire(uniqueId);
132+
Duration time = this.cooldown.getRemaining(uniqueId);
133133

134134
this.noticeService.create()
135135
.notice(translation -> translation.randomTeleport().randomTeleportDelay())

eternalcore-core/src/main/java/com/eternalcode/core/feature/repair/RepairCommand.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class RepairCommand {
2929
RepairCommand(NoticeService noticeService, RepairSettings repairSettings) {
3030
this.noticeService = noticeService;
3131
this.repairSettings = repairSettings;
32-
this.delay = new Delay<>(() -> this.repairSettings.repairDelay());
32+
this.delay = Delay.withDefault(() -> this.repairSettings.repairDelay());
3333
}
3434

3535
@Execute
@@ -73,7 +73,7 @@ void repair(@Sender Player player) {
7373
.player(player.getUniqueId())
7474
.send();
7575

76-
this.delay.markDelay(uuid, this.repairSettings.repairDelay());
76+
this.delay.markDelay(uuid);
7777
}
7878

7979
@Execute(name = "all")
@@ -117,7 +117,7 @@ void repairAll(@Sender Player player) {
117117
.player(player.getUniqueId())
118118
.send();
119119

120-
this.delay.markDelay(uuid, this.repairSettings.repairDelay());
120+
this.delay.markDelay(uuid);
121121
}
122122

123123
@Execute(name = "armor")
@@ -161,12 +161,12 @@ void repairArmor(@Sender Player player) {
161161
.player(player.getUniqueId())
162162
.send();
163163

164-
this.delay.markDelay(uuid, this.repairSettings.repairDelay());
164+
this.delay.markDelay(uuid);
165165
}
166166

167167
private boolean hasRepairDelay(UUID uuid) {
168168
if (this.delay.hasDelay(uuid)) {
169-
Duration time = this.delay.getDurationToExpire(uuid);
169+
Duration time = this.delay.getRemaining(uuid);
170170

171171
this.noticeService
172172
.create()

0 commit comments

Comments
 (0)