Skip to content

Commit 7a96b04

Browse files
committed
Fix revisionless rebuilding and db reload. Fix 1.21 Adventure issues
1 parent 7252088 commit 7a96b04

5 files changed

Lines changed: 51 additions & 8 deletions

File tree

‎changelog/6.1.1.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## Paper, Folia, and reliability
2+
- Restored `/hdb info` and other component messages on Paper 1.21.x by compiling
3+
against the Adventure API supplied by the minimum supported Paper release.
4+
- Prevented unchanged revisionless/custom catalog snapshots from rebuilding menus
5+
and preloading every head on each scheduled synchronization.

‎headdb-core/src/main/java/com/bitworksmc/headdb/core/HeadDB.java‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,12 @@ public void onEnable() {
119119
if (config.isUpdaterEnabled()) {
120120
long syncIntervalTicks = config.getDatabaseSyncIntervalMinutes() * 60L * 20L;
121121
Compatibility.runAsyncRepeating(this, () -> {
122-
int previousRevision = this.headDatabase.getCatalogRevision();
122+
List<Head> previousHeads = this.headDatabase.getHeads();
123123
this.headDatabase.update().thenAcceptAsync(heads -> {
124-
int currentRevision = this.headDatabase.getCatalogRevision();
125-
if (currentRevision != previousRevision || currentRevision < 0) {
124+
// BaseHeadDatabase retains the published list when a full
125+
// snapshot is unchanged. This also works for custom sources
126+
// that do not expose managed catalog revision headers.
127+
if (heads != previousHeads) {
126128
handleDatabaseUpdate(this.configManager.getConfig(), heads);
127129
this.menuManager.registerDefaults(this, heads);
128130
}

‎headdb-core/src/main/java/com/bitworksmc/headdb/implementation/BaseHeadDatabase.java‎

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,17 @@ private List<Head> loadFullSnapshot() {
161161
for (String sourceUrl : sourceUrls) {
162162
try {
163163
FetchedCatalog fetched = fetchHeads(sourceUrl);
164-
Snapshot loadedSnapshot = buildSnapshot(fetched.heads());
165-
this.snapshot = loadedSnapshot;
164+
Snapshot currentSnapshot = this.snapshot;
165+
if (!sameHeads(currentSnapshot, fetched.heads())) {
166+
this.snapshot = buildSnapshot(fetched.heads());
167+
}
166168
this.catalogRevision = fetched.revision();
167169
this.activeSource = sourceUrl;
168-
persistCatalogCache(loadedSnapshot.heads(), fetched.revision());
170+
persistCatalogCache(this.snapshot.heads(), fetched.revision());
169171

170172
long elapsed = System.currentTimeMillis() - start;
171173
LOGGER.debug("Update took {} seconds ({}ms total)", TimeUnit.MILLISECONDS.toSeconds(elapsed), elapsed);
172-
return loadedSnapshot.heads();
174+
return this.snapshot.heads();
173175
} catch (IOException | RuntimeException ex) {
174176
lastException = ex;
175177
LOGGER.warn("Failed to load heads from '{}': {}", sourceUrl, ex.getMessage());
@@ -724,6 +726,19 @@ private static boolean sameHead(Head left, Head right) {
724726
&& Objects.equals(left.getTags(), right.getTags());
725727
}
726728

729+
private static boolean sameHeads(@Nullable Snapshot left, List<Head> right) {
730+
if (left == null || left.heads().size() != right.size()) {
731+
return false;
732+
}
733+
for (int i = 0; i < left.heads().size(); i++) {
734+
Head candidate = right.get(i);
735+
if (candidate == null || !sameHead(left.heads().get(i), candidate)) {
736+
return false;
737+
}
738+
}
739+
return true;
740+
}
741+
727742
private static String rootMessage(Throwable failure) {
728743
Throwable current = failure;
729744
while (current.getCause() != null) current = current.getCause();

‎headdb-core/src/test/java/com/bitworksmc/headdb/implementation/BaseHeadDatabaseTest.java‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,24 @@ void publishedCollectionsCannotBeMutated() {
154154
assertThrows(UnsupportedOperationException.class, () -> database.getByTags("Fruit").clear());
155155
}
156156

157+
@Test
158+
void unchangedRevisionlessSnapshotKeepsPublishedList() {
159+
AtomicInteger requests = new AtomicInteger();
160+
server.createContext("/heads", exchange -> {
161+
requests.incrementAndGet();
162+
respond(exchange, 200, HEADS_JSON);
163+
});
164+
BaseHeadDatabase database = database("/heads", Index.ID);
165+
166+
List<Head> initial = database.update().join();
167+
List<Head> refreshed = database.update().join();
168+
169+
assertSame(initial, refreshed);
170+
assertSame(initial, database.getHeads());
171+
assertEquals(-1, database.getCatalogRevision());
172+
assertEquals(2, requests.get());
173+
}
174+
157175
@Test
158176
void appliesRevisionChangesAndRestoresTheSavedCatalog() {
159177
AtomicInteger snapshotRequests = new AtomicInteger();

‎pom.xml‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
<properties>
2323
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2424
<maven.compiler.release>21</maven.compiler.release>
25-
<adventure.version>5.2.0</adventure.version>
25+
<!-- Compile against the Adventure API supplied by the minimum supported
26+
Paper release. Newer Adventure runtimes retain compatibility with
27+
clients compiled against this API, while the reverse is not true. -->
28+
<adventure.version>4.17.0</adventure.version>
2629
<annotations.version>26.1.0</annotations.version>
2730
<paper.minecraft.version>26.2</paper.minecraft.version>
2831
<paper.version>1.21-R0.1-SNAPSHOT</paper.version>

0 commit comments

Comments
 (0)