This commit is contained in:
Josh Hawkins 2026-04-28 22:42:15 -05:00 committed by GitHub
commit 12967aa56f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import base64
import json import json
import logging import logging
import os import os
import sys
import threading import threading
from json.decoder import JSONDecodeError from json.decoder import JSONDecodeError
from multiprocessing.synchronize import Event as MpEvent from multiprocessing.synchronize import Event as MpEvent
@ -52,6 +53,14 @@ class EmbeddingProcess(FrigateProcess):
self.stop_event, self.stop_event,
) )
maintainer.start() maintainer.start()
maintainer.join()
# If the maintainer thread exited but no shutdown was requested, it
# crashed. Surface as a non-zero exit so the watchdog restarts us
# instead of treating the silent thread death as a clean shutdown.
if not self.stop_event.is_set():
logger.error("Embeddings maintainer thread exited unexpectedly")
sys.exit(1)
class EmbeddingsContext: class EmbeddingsContext:

View File

@ -28,6 +28,7 @@ class MonitoredProcess:
restart_timestamps: deque[float] = field( restart_timestamps: deque[float] = field(
default_factory=lambda: deque(maxlen=MAX_RESTARTS) default_factory=lambda: deque(maxlen=MAX_RESTARTS)
) )
clean_exit_logged: bool = False
def is_restarting_too_fast(self, now: float) -> bool: def is_restarting_too_fast(self, now: float) -> bool:
while ( while (
@ -72,7 +73,9 @@ class FrigateWatchdog(threading.Thread):
exitcode = entry.process.exitcode exitcode = entry.process.exitcode
if exitcode == 0: if exitcode == 0:
logger.info("Process %s exited cleanly, not restarting", entry.name) if not entry.clean_exit_logged:
logger.info("Process %s exited cleanly, not restarting", entry.name)
entry.clean_exit_logged = True
return return
logger.warning( logger.warning(

View File

@ -10,13 +10,16 @@ import axios from "axios";
import { toast } from "sonner"; import { toast } from "sonner";
import { useJobStatus } from "@/api/ws"; import { useJobStatus } from "@/api/ws";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import { LuCheck, LuX } from "react-icons/lu"; import { LuCheck, LuExternalLink, LuX } from "react-icons/lu";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil"; import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
import { MediaSyncResults, MediaSyncStats } from "@/types/ws"; import { MediaSyncResults, MediaSyncStats } from "@/types/ws";
import { useDocDomain } from "@/hooks/use-doc-domain";
import { Link } from "react-router-dom";
export default function MediaSyncSettingsView() { export default function MediaSyncSettingsView() {
const { t } = useTranslation("views/settings"); const { t } = useTranslation("views/settings");
const { getLocaleDocUrl } = useDocDomain();
const [selectedMediaTypes, setSelectedMediaTypes] = useState<string[]>([ const [selectedMediaTypes, setSelectedMediaTypes] = useState<string[]>([
"all", "all",
]); ]);
@ -109,13 +112,25 @@ export default function MediaSyncSettingsView() {
<Heading as="h4" className="mb-2 hidden md:block"> <Heading as="h4" className="mb-2 hidden md:block">
{t("maintenance.sync.title")} {t("maintenance.sync.title")}
</Heading> </Heading>
<div className="max-w-6xl"> <div className="max-w-6xl">
<div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-muted-foreground"> <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-muted-foreground">
<p>{t("maintenance.sync.desc")}</p> <p>{t("maintenance.sync.desc")}</p>
<div className="flex items-center text-primary-variant">
<Link
to={getLocaleDocUrl(
"configuration/record#syncing-media-files-with-disk",
)}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", { ns: "common" })}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</div> </div>
</div> </div>
<div className="space-y-6"> <div className="space-y-6">
{/* Media Types Selection */} {/* Media Types Selection */}
<div> <div>