@@ -69,6 +69,10 @@ next edited.
6969
7070Github issue #135
7171
72+ ** Resolved (` 320fb47 ` , "#121 allow hot reloads on config").** ` isMarkerType ` now null-checks the
73+ ` prefixGroupMap.get(prefix) ` lookup before calling ` .type() ` , returning ` false ` instead of throwing when a
74+ persisted sign's prefix isn't in the current config.
75+
7276### 4. ` SignProvider.loadSigns ` 's load loop has no per-entry exception handling — one bad entry drops the whole file
7377** ` src/main/java/com/tpwalke2/bluemapsignmarkers/core/signs/persistence/SignProvider.java:59-61 ` **
7478``` java
@@ -236,11 +240,14 @@ a stale replayed value, or a sign removed during the race can be silently re-add
236240 (` BlueMapSignMarkersMod.java:42 ` , ` SignManager.java:136 ` ). Two independently-hardcoded literals that only happen
237241 to match today; editing one without the other silently breaks playerId-preservation logic on chunk load vs.
238242 player edit.
239- - ** ` ServerPathProvider.java ` is dead code** — no callers anywhere in ` src/ ` , and it's referenced elsewhere as
240- in-progress/unwired. Should be wired up or removed.
241- - ** Charset mismatch between save and load** , both in ` ConfigProvider.java ` (` saveConfig ` uses platform-default
242- ` FileWriter ` , ` loadConfig ` reads explicit UTF-8) and ` SignProvider.java ` (same pattern). Non-ASCII marker-group
243- names or sign text is at risk of encoding mismatch across a restart if the JVM default charset isn't UTF-8.
243+ - ~~ ** ` ServerPathProvider.java ` is dead code** ~~ — ** Resolved.** ` BlueMapSignMarkersMod ` now `implements ...
244+ ServerPathProvider`; no longer unwired.
245+ - ** Charset mismatch between save and load** in ` ConfigProvider.java ` (` saveConfig ` uses platform-default
246+ ` FileWriter ` , ` loadConfig ` reads explicit UTF-8) — still open. Non-ASCII marker-group names are at risk of
247+ encoding mismatch across a restart if the JVM default charset isn't UTF-8. The sign-file half of this finding
248+ (originally also flagged in ` SignProvider.java ` ) is ** resolved** : that class was replaced by the region-sharded
249+ storage classes (` RegionShardedSignEntryWriter ` /` Loader ` , ` LegacySignFileMigrator ` , ` #109 ` ), which consistently
250+ use ` Files.writeString ` /` readString ` with explicit UTF-8 on both sides.
244251- ** No fail-fast config validation** — nothing checks marker-group prefixes are non-empty, that REGEX prefixes
245252 compile, or that prefixes are unique across groups at load time; bad data is only caught later, silently or by
246253 crashing (see finding #8 ).
@@ -257,9 +264,13 @@ a stale replayed value, or a sign removed during the race can be silently re-add
257264- ** ` logProcessingMessage ` logs full raw sign text at INFO unconditionally** , sanitizing only ` \n `
258265 (` BlueMapAPIConnector.java:97-102 ` ) — other control characters (` \r ` , ANSI escapes) aren't sanitized, a minor
259266 log-injection/log-noise vector.
260- - ** Cache-key growth risk** : ` MarkerSetIdentifier ` /` markerSetsCache ` keys are value-equality on the * entire*
261- ` MarkerGroup ` record, so any config field change (icon, offsets, distances) between reloads produces a new,
262- never-evicted cache entry. Speculative — depends on a config-reload path not covered in this review.
267+ - ** Cache-key growth risk, now confirmed rather than speculative** : ` MarkerSetIdentifier ` /` markerSetsCache ` keys
268+ are value-equality on the * entire* ` MarkerGroup ` record, so any config field change (icon, offsets, distances)
269+ between reloads produces a new, never-evicted cache entry. Originally speculative, pending a config-reload path
270+ not covered in this review — that path now exists (` SignManager.reloadConfig() ` , added by ` #121 ` hot-reload
271+ work) and confirms the risk: it rebuilds the prefix map but never calls ` blueMapAPIConnector.resetQueue() ` , so
272+ ` markerSetsCache ` is never cleared on a live config reload. Worth reconsidering as Medium severity rather than
273+ Low.
263274- ** ` SignManager ` : dual-sided signs with different prefixes mix marker-group semantics** — the marker's group
264275 (icon/type/visibility) comes from whichever side ` getPrefix ` picks (front preferred), but ` getDetail ` merges
265276 * both* sides' text regardless of whether they matched different groups.
@@ -271,8 +282,10 @@ a stale replayed value, or a sign removed during the race can be silently re-add
271282
272283## Nitpick
273284
274- - ` ConfigManager.loadCoreConfig() ` is ` synchronized ` despite being called exactly once from a ` static final ` field
275- initializer, which the JLS already makes thread-safe — the modifier is misleading, not harmful.
285+ - ~~ ` ConfigManager.loadCoreConfig() ` is ` synchronized ` despite being called exactly once from a ` static final `
286+ field initializer~~ — ** stale** : the premise no longer holds. Config hot-reload work (` #121 ` ) restructured
287+ ` ConfigManager ` : ` coreConfig ` is now ` volatile ` and lazily loaded, and ` reload() ` /` reload(Path) ` are
288+ ` synchronized ` to guard concurrent hot-reloads for real, not a redundant guard on a one-time static initializer.
276289- The default single-` [poi] ` -group literal is duplicated verbatim across ` BMSMConfigV2 ` and ` LoadingBMSMConfigV2 `
277290 with no shared constant.
278291- ` SignManager.isMarkerType ` re-derives ` getPrefix(signEntry) ` that's already computed a few lines later —
0 commit comments