Releases: MrRobotoGit/tiramisu
Release list
v1.9.12
Features
- Preferred/excluded audio language matching is now configurable via
config.json(language.preferred_terms,language.preferred_flags,language.excluded_flags) instead of hardcoded in source — closes #18 - New Languages box in the Control Panel (
:9080/control) with a flag picker (ISO country codes, generated to emoji with no lookup table) to add/remove preferred and excluded languages without editing config.json by hand - Existing installs keep their current behavior automatically (defaults applied when the
languagekey is absent fromconfig.json) — no migration needed
Fixes
- TV sync engine's "ita" language term matched as a substring (e.g. inside "capitale"), unlike the Movie engine which already required a word boundary — both engines now share the same matching logic and this false-positive is fixed
v1.9.11
Fixes
- Read-ahead buffer pool: recycle by capacity instead of exact length, so chunks from torrents with non-power-of-two piece lengths (~25% of the library) stay poolable instead of draining the pool
- Sync engines (movie/TV) now invalidate FUSE-layer state (dircache, registry, active pump/handles) when removing a stub file out-of-band, instead of a bare
os.Removethat bypassed the Unlink handler — this previously let Plex register a replaced file as a ghost duplicate media version during the stale-cache window - Sync engines now log Plex library refresh failures instead of silently swallowing them
v1.9.1
New
- Tail-hedging now extends beyond warmup to steady-state playback: hedges stalled requests when the pump's buffer lead thins, confirmed working in production
- Banned peer count (V304 session ban) exposed on
/metricsand the Health Monitor dashboard
Docs
- README: added Adaptive Chunk Size, AdaptiveShield, TailHedge, PEXChurn to the feature list
- README: restyled header (ASCII banner, badges, semantic H1), added an FAQ section, removed em-dashes
- Adaptive Shield section updated to reflect the real escalating clean-streak behavior (30/60/90/120s)
v1.9.0 — Tiramisu
GoStream is now Tiramisu. Same project, same codebase, same engine — just a new name.
Rebranding
- Go module, binary, systemd service, config keys, and all paths renamed
gostream→tiramisu - GitHub repo renamed to
MrRobotoGit/tiramisu(old links still redirect) - Docker Hub and GHCR images published under
mrrobotogit/tiramisu - macOS toolbar menu bar app renamed and recompiled (
Tiramisu.app) GoStorm(the embedded torrent engine) keeps its own name — it's a distinct component
Compatibility
- Docker: new
TIRAMISU_*environment variables are primary; oldGOSTREAM_*ones still work as fallback aliases - Existing installs: state DB, config, and logs are not touched automatically — see the README's upgrade note before re-running
install.sh
Fixes found along the way
install.sh:user_allow_otherFUSE setup was skipped whenever system dependencies were already installed (e.g. on Raspberry Pi OS, or a second run of the installer), causing a silent FUSE mount failure at first start- Fixed several
.gitignoreand sync-script exclude patterns that were unanchored and either hid files from sync or silently untracked legitimate source files
v1.8.56
Aggressive Peer Management
New aggressive_peer_management flag (GoStorm live setting, default off):
- Warmup duration histogram in
/metrics(always on) - PEX churn: drops peers lacking pieces for the file's real warmup range during cold start, with a 10s per-IP cooldown before re-probing
- Tail-hedging: fires a duplicate request to the next-best peer when a warmup-region request exceeds the observed p95 latency, with a circuit breaker if the hedge rate spikes (shared VPN tunnel saturation)
Fixes
- WARMUP state stuck bug: linear playback (no seek) never transitioned out of the warmup state, causing sustained CPU overhead for the rest of playback on every stream
- CloseHash piece-buffer memory leak (dead code, never called)
- Goroutine reuse for tracker scraping and piece hashing
- Non-blocking prefetch goroutine spawning
- Lowered 4K movie sync max size cap 60GB -> 40GB (avoids picking bandwidth-heavy remuxes the swarm can't sustain)
Dashboard
- Global cache hit rate stat
- Mobile/desktop responsive font sizing
- Dev-build version badge no longer shows a false "update available" pill
v1.8.55
v1.8.54
v1.8.52
fix: wire up dead CloseHash() call, fixing critical piece-buffer memory leak
Storage.CloseHash() removes a torrent's *Cache (and all its MemPiece piece
buffers received from peers) from the global Storage.caches map. It was
defined but never called anywhere in the codebase - Torrent.Close() only
removed the torrent from bt.torrents and dropped the underlying anacrolix
torrent, leaving its Cache permanently referenced in Storage.caches for the
rest of the process lifetime.
Every torrent ever touched (movie/TV sync, watchlist, Plex library scans)
accumulated its piece buffers in RAM forever, even after expiring via the
normal 45s-timeout torrent reaper. Heap profile taken during a combined
Plex-scan + movie-sync + TV-sync stress test showed 6.1GB (89% of the heap)
reachable via torrstor.(*MemPiece).WriteAt, all attributed to peer connection
read loops (Peer.receiveChunk -> PeerConn.mainReadLoop) - consistent with
buffers from every torrent activated since process start never being freed.
System swap was at 5.0/5.1GB used (near exhaustion) when captured.
Now calls storage.CloseHash(hash) in Torrent.Close(), covering both the
expiry path (UpdateStats -> RemoveTorrent) and explicit removal
(DropTorrent API). Cache.Close() is idempotent (guarded by isClosed), so
this is safe even if anacrolix's storage.TorrentImpl.Close callback also
fires for the same hash.
Full Changelog: v1.8.51...v1.8.52
v1.8.51
v1.8.50
fix: bound stream reads by context timeout, fix third adaptive-chunk-size gap
Stream() only used the context timeout to guard the HTTP response write side;
http.ServeContent's internal reads went through torrstor.Reader.Read(), which
called the underlying anacrolix reader with context.Background(). A stalled
swarm (no seeders for the requested range) left that goroutine and its
torrstor.Reader blocked until the whole torrent closed (up to 2h), instead of
being bounded by streamTimeout. Added torrstor.Reader.ReadContext and a
ctxReader wrapper in stream.go so http.ServeContent's reads are properly
cancelled on timeout.
Also fixed a third prefetch site (main.go, no-active-pump fallback) still
sizing its fetch with the fixed ReadAheadBase instead of the adaptive
raCache.ChunkSize(h.path), same collision/miss class as 4005a14 and the two
WarmLanding sites fixed today.
Full Changelog: v1.8.49...v1.8.50