mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
Match the folder-watch reconcile to the legacy watched-folder poll
This commit is contained in:
+29
@@ -24,6 +24,11 @@ public class ConfigInitializer {
|
||||
|
||||
private static final int MIN_SETTINGS_FILE_LINES = 31;
|
||||
|
||||
/** The shipped default before folder-watch had to cover converted legacy watched folders. */
|
||||
private static final int OLD_WATCH_RECONCILE_SECONDS = 300;
|
||||
|
||||
private static final int WATCH_RECONCILE_SECONDS = 60;
|
||||
|
||||
public void ensureConfigExists() throws IOException, URISyntaxException {
|
||||
// 1) If settings file doesn't exist, create from template
|
||||
Path destPath = Path.of(InstallationPathConfig.getSettingsPath());
|
||||
@@ -80,6 +85,7 @@ public class ConfigInitializer {
|
||||
|
||||
migrateEnterpriseEditionToPremium(settingsFile, settingsTemplateFile);
|
||||
migrateProFeaturesKeyCasing(settingsFile, settingsTemplateFile);
|
||||
migrateWatchReconcileDefault(settingsFile);
|
||||
|
||||
boolean changesMade =
|
||||
settingsTemplateFile.updateValuesFromYaml(settingsFile, settingsTemplateFile);
|
||||
@@ -102,6 +108,29 @@ public class ConfigInitializer {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove post migration
|
||||
// A legacy watched folder polled every 60s, and converting one into a folder-watch policy must
|
||||
// not make it slower. The reconcile is the only retry for a file the readiness check deferred,
|
||||
// so at 300s a file that landed mid-sweep waited five minutes. Existing installs carry the old
|
||||
// default forward on upgrade, so lower it here - but only when it is still exactly the old
|
||||
// default, since any other value is a deliberate choice.
|
||||
void migrateWatchReconcileDefault(YamlHelper yaml) {
|
||||
// getValueByExactKeyPath yields the scalar as written, i.e. a String, not a Number.
|
||||
Object current = yaml.getValueByExactKeyPath("policies", "watchReconcileSeconds");
|
||||
if (current == null
|
||||
|| !String.valueOf(current)
|
||||
.trim()
|
||||
.equals(String.valueOf(OLD_WATCH_RECONCILE_SECONDS))) {
|
||||
return;
|
||||
}
|
||||
yaml.updateValue(List.of("policies", "watchReconcileSeconds"), WATCH_RECONCILE_SECONDS);
|
||||
log.info(
|
||||
"Lowered policies.watchReconcileSeconds from {} to {} so converted watched folders"
|
||||
+ " keep their legacy poll interval",
|
||||
OLD_WATCH_RECONCILE_SECONDS,
|
||||
WATCH_RECONCILE_SECONDS);
|
||||
}
|
||||
|
||||
// TODO: Remove post migration
|
||||
private void migrateEnterpriseEditionToPremium(YamlHelper yaml, YamlHelper template) {
|
||||
if (yaml.getValueByExactKeyPath("enterpriseEdition", "enabled") != null) {
|
||||
|
||||
@@ -221,9 +221,10 @@ public class ApplicationProperties {
|
||||
/**
|
||||
* How often (seconds) the folder-watch trigger reconciles its watch registrations and
|
||||
* re-runs every folder-watch policy as a safety net for filesystem events that were missed
|
||||
* (NFS, bind mounts, inotify-queue overflow).
|
||||
* (NFS, bind mounts, inotify-queue overflow). Matches the legacy watched-folder scanner's
|
||||
* poll, so a converted automation picks a file up no slower than it used to.
|
||||
*/
|
||||
private long watchReconcileSeconds = 300;
|
||||
private long watchReconcileSeconds = 60;
|
||||
|
||||
/**
|
||||
* How long (milliseconds) the folder-watch trigger keeps draining filesystem events after
|
||||
|
||||
+41
@@ -30,6 +30,47 @@ class ConfigInitializerTest {
|
||||
producer: Stirling-PDF
|
||||
""";
|
||||
|
||||
@Test
|
||||
void migrateWatchReconcileDefault_lowersTheOldShippedDefault() {
|
||||
YamlHelper existing =
|
||||
new YamlHelper(
|
||||
LOAD_SETTINGS,
|
||||
"""
|
||||
policies:
|
||||
scheduleSweepSeconds: 60
|
||||
watchReconcileSeconds: 300
|
||||
""");
|
||||
|
||||
new ConfigInitializer().migrateWatchReconcileDefault(existing);
|
||||
|
||||
assertEquals("60", existing.getValueByExactKeyPath("policies", "watchReconcileSeconds"));
|
||||
// Untouched neighbours prove the rewrite is scoped to the one key.
|
||||
assertEquals("60", existing.getValueByExactKeyPath("policies", "scheduleSweepSeconds"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void migrateWatchReconcileDefault_keepsADeliberateValue() {
|
||||
YamlHelper existing =
|
||||
new YamlHelper(
|
||||
LOAD_SETTINGS,
|
||||
"""
|
||||
policies:
|
||||
watchReconcileSeconds: 900
|
||||
""");
|
||||
|
||||
new ConfigInitializer().migrateWatchReconcileDefault(existing);
|
||||
|
||||
assertEquals("900", existing.getValueByExactKeyPath("policies", "watchReconcileSeconds"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void migrateWatchReconcileDefault_toleratesAMissingKey() {
|
||||
YamlHelper existing =
|
||||
new YamlHelper(LOAD_SETTINGS, "policies:\n scheduleSweepSeconds: 60\n");
|
||||
|
||||
assertDoesNotThrow(() -> new ConfigInitializer().migrateWatchReconcileDefault(existing));
|
||||
}
|
||||
|
||||
@Test
|
||||
void migrateProFeaturesKeyCasing_carriesForwardLegacyPascalCaseValues() {
|
||||
// An existing install whose settings.yml still uses the old PascalCase keys.
|
||||
|
||||
@@ -415,7 +415,7 @@ policies:
|
||||
# disabled in SaaS mode.
|
||||
allowedFolderRoots: [] # e.g. ["/data/inbox", "/data/outbox"]
|
||||
scheduleSweepSeconds: 60 # How often (seconds) scheduled policies are checked for being due
|
||||
watchReconcileSeconds: 300 # How often (seconds) folder-watch re-syncs watches and re-runs as a safety net for missed events
|
||||
watchReconcileSeconds: 60 # How often (seconds) folder-watch re-syncs watches and re-runs as a safety net for missed events
|
||||
watchQuietPeriodMs: 500 # How long (ms) folder-watch coalesces a burst of file events into a single run
|
||||
streamTimeoutMs: 1800000 # SSE timeout (ms) for live run-progress streams
|
||||
runExpiryMinutes: 30 # How long (minutes) a finished run's in-memory state is kept before eviction
|
||||
|
||||
Reference in New Issue
Block a user