diff --git a/cmd/altmount/cmd/serve.go b/cmd/altmount/cmd/serve.go
index 0ae72a38b..9c63c04ac 100644
--- a/cmd/altmount/cmd/serve.go
+++ b/cmd/altmount/cmd/serve.go
@@ -178,7 +178,7 @@ func runServe(cmd *cobra.Command, args []string) error {
configManager.OnConfigChange(func(oldConfig, newConfig *config.Config) {
structuralChange := oldConfig.SegmentCache.CachePath != newConfig.SegmentCache.CachePath ||
oldConfig.SegmentCache.MaxSizeGB != newConfig.SegmentCache.MaxSizeGB ||
- oldConfig.SegmentCache.ExpiryHours != newConfig.SegmentCache.ExpiryHours
+ intPtrValue(oldConfig.SegmentCache.ExpiryHours) != intPtrValue(newConfig.SegmentCache.ExpiryHours)
if !structuralChange {
return
@@ -439,3 +439,13 @@ func waitForHTTPServer(ctx context.Context, port int) error {
}
}
+
+// intPtrValue returns the value pointed to by p, or 0 when p is nil. It is used
+// to compare optional integer config fields (e.g. segment cache ExpiryHours) by
+// value rather than by pointer identity.
+func intPtrValue(p *int) int {
+ if p == nil {
+ return 0
+ }
+ return *p
+}
diff --git a/cmd/altmount/cmd/setup.go b/cmd/altmount/cmd/setup.go
index 50846f61a..54357cdf6 100644
--- a/cmd/altmount/cmd/setup.go
+++ b/cmd/altmount/cmd/setup.go
@@ -315,10 +315,18 @@ func initializeSegmentCache(ctx context.Context, cfg *config.Config, source *seg
return nil
}
+ // ExpiryHours is normalized in config.Validate (nil -> 24h); guard against
+ // nil defensively in case the cache is initialized outside the load path. A
+ // zero value is preserved and means "cache forever".
+ expiryHours := 24
+ if cfg.SegmentCache.ExpiryHours != nil {
+ expiryHours = *cfg.SegmentCache.ExpiryHours
+ }
+
mgrCfg := segcache.ManagerConfig{
CachePath: cfg.SegmentCache.CachePath,
MaxSizeBytes: int64(cfg.SegmentCache.MaxSizeGB) * 1024 * 1024 * 1024,
- ExpiryDuration: time.Duration(cfg.SegmentCache.ExpiryHours) * time.Hour,
+ ExpiryDuration: time.Duration(expiryHours) * time.Hour,
}.WithDefaults()
mgr, err := segcache.NewManager(mgrCfg, slog.Default().With("component", "segcache"))
diff --git a/frontend/src/components/config/StreamingConfigSection.tsx b/frontend/src/components/config/StreamingConfigSection.tsx
index 502f713de..4d3612898 100644
--- a/frontend/src/components/config/StreamingConfigSection.tsx
+++ b/frontend/src/components/config/StreamingConfigSection.tsx
@@ -131,7 +131,8 @@ export function StreamingConfigSection({
Playback Failure Masking
- Debounce transient streaming errors (like propagation delays) by requiring multiple consecutive playback failures before triggering a redownload.
+ Debounce transient streaming errors (like propagation delays) by requiring multiple
+ consecutive playback failures before triggering a redownload.
Failure Threshold
- Number of consecutive failures required before declaring a file corrupted and requesting repair.
+ Number of consecutive failures required before declaring a file corrupted and
+ requesting repair.
135
@@ -300,21 +304,30 @@ export function StreamingConfigSection({
Cache Expiry
- How long cached segments are kept before automatic eviction.
+ How long cached segments are kept before automatic eviction. Set to 0 to keep
+ them forever (bounded only by the maximum cache size).