plex deadlock + version showing stale + "disco" screen after docker update fixes
This commit is contained in:
@@ -40,7 +40,7 @@ class PreferencesService:
|
||||
self._settings = settings
|
||||
self._config_path = settings.config_file_path
|
||||
self._config_cache: Optional[dict] = None
|
||||
self._cache_lock = threading.Lock()
|
||||
self._cache_lock = threading.RLock()
|
||||
self._migrate_musicbrainz_settings()
|
||||
self._ensure_instance_id()
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@ from fastapi.responses import FileResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
|
||||
_NO_CACHE_HEADERS = {"Cache-Control": "no-cache"}
|
||||
|
||||
|
||||
def mount_frontend(app: FastAPI):
|
||||
backend_static = Path(__file__).parent / "static"
|
||||
frontend_root = Path(__file__).resolve().parents[1] / "frontend"
|
||||
@@ -83,7 +86,7 @@ def mount_frontend(app: FastAPI):
|
||||
@app.get("/")
|
||||
async def serve_root():
|
||||
if index_html.exists():
|
||||
return FileResponse(index_html)
|
||||
return FileResponse(index_html, headers=_NO_CACHE_HEADERS)
|
||||
raise HTTPException(status_code=404, detail="Frontend not built yet")
|
||||
|
||||
@app.get("/{full_path:path}")
|
||||
@@ -91,5 +94,5 @@ def mount_frontend(app: FastAPI):
|
||||
if full_path.startswith("api"):
|
||||
raise HTTPException(status_code=404, detail="API route not found")
|
||||
if index_html.exists():
|
||||
return FileResponse(index_html)
|
||||
return FileResponse(index_html, headers=_NO_CACHE_HEADERS)
|
||||
raise HTTPException(status_code=404, detail="Frontend not built yet")
|
||||
|
||||
@@ -77,6 +77,43 @@ class TestCreatePlexPin:
|
||||
assert resp.status_code == 500
|
||||
|
||||
|
||||
class TestGetOrCreateSettingNoDeadlock:
|
||||
def test_get_or_create_setting_does_not_deadlock(self, tmp_path):
|
||||
import threading
|
||||
|
||||
from core.config import Settings
|
||||
from services.preferences_service import PreferencesService
|
||||
|
||||
config_path = tmp_path / "config.json"
|
||||
settings = Settings(
|
||||
root_app_dir=tmp_path,
|
||||
config_file_path=config_path,
|
||||
cache_dir=tmp_path / "cache",
|
||||
library_db_path=tmp_path / "cache" / "library.db",
|
||||
queue_db_path=tmp_path / "cache" / "queue.db",
|
||||
)
|
||||
|
||||
result = None
|
||||
exc = None
|
||||
|
||||
def run():
|
||||
nonlocal result, exc
|
||||
try:
|
||||
prefs = PreferencesService(settings)
|
||||
result = prefs.get_or_create_setting("plex_client_id", lambda: "test-client-id")
|
||||
result = (result, prefs.get_or_create_setting("plex_client_id", lambda: "other"))
|
||||
except Exception as e:
|
||||
exc = e
|
||||
|
||||
t = threading.Thread(target=run)
|
||||
t.start()
|
||||
t.join(timeout=5)
|
||||
assert not t.is_alive(), "Deadlock detected: PreferencesService hung for 5s"
|
||||
assert exc is None
|
||||
assert result[0] == "test-client-id"
|
||||
assert result[1] == "test-client-id"
|
||||
|
||||
|
||||
class TestPollPlexPin:
|
||||
def test_poll_pending(self, auth_client):
|
||||
resp = auth_client.get("/plex/auth/poll?pin_id=12345")
|
||||
|
||||
@@ -30,7 +30,8 @@ export const getVersionQuery = () =>
|
||||
staleTime: CACHE_TTL.VERSION_INFO,
|
||||
queryKey: VersionQueryKeyFactory.info(),
|
||||
queryFn: ({ signal }) => api.global.get<VersionInfo>(API.version.info(), { signal }),
|
||||
refetchOnWindowFocus: false
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnMount: 'always'
|
||||
}));
|
||||
|
||||
export const getUpdateCheckQuery = () =>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import { AlertTriangle, Home, RotateCw } from 'lucide-svelte';
|
||||
import { page } from '$app/state';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Error - MusicSeerr</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="w-full px-2 sm:px-4 lg:px-8 py-4 sm:py-8 max-w-7xl mx-auto">
|
||||
<div class="flex flex-col items-center justify-center py-20 gap-4 text-center">
|
||||
<AlertTriangle class="h-16 w-16 text-error/40" />
|
||||
<h1 class="text-lg font-semibold text-base-content/80">Something went wrong</h1>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{page.error?.message ?? 'An unexpected error occurred'}
|
||||
</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="/" class="btn btn-ghost btn-sm">
|
||||
<Home class="h-4 w-4" />
|
||||
Home
|
||||
</a>
|
||||
<button class="btn btn-accent btn-sm" onclick={() => location.reload()}>
|
||||
<RotateCw class="h-4 w-4" />
|
||||
Retry
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user