perf(fuse): eliminate per-read goroutine churn - #463
Merged
Conversation
Two independent improvements to reduce CPU overhead when streaming via FUSE: **1. Single IO worker per handle (Linux/hanwen)** Replace `readWithContext`/`seekWithContext` which spawned a new goroutine and buffered channel on every FUSE read call. A persistent background worker goroutine per Handle now serializes all IO, with requests dispatched via a buffered channel and results returned through a `sync.Pool`-backed channel. Eliminates ~24+ goroutine+channel allocations per second at 25 Mbps. **2. In-memory LRU hot cache for segment cache** `SegmentCache.Get()` previously called `os.ReadFile()` on every cache hit, allocating ~750 KB per segment read. A new LRU hot cache (default 256 MiB, ~341 segments) serves recently-accessed segments directly from memory, avoiding repeated disk I/O and GC pressure from large heap allocations. Configurable via `segment_cache.hot_cache_max_size_mb` in config. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
defer runs after the function returns, which is after AssertExpectations checks that Close() was called. Fixed by calling Release explicitly before AssertExpectations in each MockFile-based test; the deferred call remains as a panic-safety net (Release is idempotent). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
yoshitaka420
pushed a commit
to yoshitaka420/altmount
that referenced
this pull request
Jun 1, 2026
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
readWithContext/seekWithContextgoroutines with a single persistent IO worker goroutine perHandle. Previously every FUSE read spawned a goroutine + buffered channel (~24+/sec at 25 Mbps); now one worker per open file handles all IO via a request channel with pooled result channels.Test plan
go test -race ./internal/nzbfilesystem/segcache/...passesGOOS=linux go vet ./internal/fuse/backend/hanwen/...passes (tests require native Linux with CGO)hot_cache_max_size_mb: 0in config and verify it falls back to 256 MiB default🤖 Generated with Claude Code