feat: Android download page, analysis retry and a collapsible search
ci / api / api (push) Successful in 37s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 46s
ci / db / db (push) Failing after 14s
ci / recommender / recommender (push) Successful in 51s
ci / ts / ts (packages + web) (push) Successful in 57s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m2s
ci / api / api (push) Successful in 37s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 46s
ci / db / db (push) Failing after 14s
ci / recommender / recommender (push) Successful in 51s
ci / ts / ts (packages + web) (push) Successful in 57s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m2s
- /android is a public page with the latest APK, the server address to copy and three install steps; linked from the sign-in screen and the profile menu - failed audio analysis can be retried from the library page, which also shows the most common error; the analyzer no longer burns attempts on files that are missing because the disk is not mounted - the top bar search folds into a round button and slides open on click, "/" or Ctrl+K Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2d49cb3f19
commit
fda6ed48ab
27 files changed
+757
-277
No files matched your search
@@ -20,6 +20,7 @@ log = logging.getLogger(__name__)
|
||||
MAX_ATTEMPTS = 3
|
||||
MAX_DURATION_S = 15 * 60
|
||||
IDLE_SLEEP_S = 10.0
|
||||
MISSING_SLEEP_S = 60.0 # файлы пропали целиком — ждём, пока смонтируют диск
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -168,6 +169,18 @@ class Worker:
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
def postpone(self, conn: psycopg.Connection[Any], track_ids: list[str]) -> None:
|
||||
"""Файла нет на диске (не смонтирован?) — обратно в очередь, попытка не засчитывается."""
|
||||
conn.execute(
|
||||
"""
|
||||
UPDATE analysis_jobs SET status = 'queued', attempts = greatest(attempts - 1, 0),
|
||||
error = 'file not found — is the disk mounted?', updated_at = now()
|
||||
WHERE track_id = ANY(%s::uuid[])
|
||||
""",
|
||||
(track_ids,),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
def requeue_stale(self, conn: psycopg.Connection[Any]) -> None:
|
||||
"""Задачи, брошенные упавшим воркером, и признаки старой версии анализатора — снова в очередь."""
|
||||
conn.execute(
|
||||
@@ -189,6 +202,16 @@ class Worker:
|
||||
self.requeue_stale(conn)
|
||||
while True:
|
||||
jobs = self.claim(conn, self.workers * 2)
|
||||
missing = [j for j in jobs if not Path(j.path).exists()]
|
||||
if missing:
|
||||
self.postpone(conn, [j.track_id for j in missing])
|
||||
jobs = [j for j in jobs if j not in missing]
|
||||
if not jobs:
|
||||
log.warning(
|
||||
"analysis: %d files not found, waiting — is the disk mounted?", len(missing)
|
||||
)
|
||||
time.sleep(MISSING_SLEEP_S)
|
||||
continue
|
||||
if not jobs:
|
||||
time.sleep(IDLE_SLEEP_S)
|
||||
continue
|
||||
|
||||
Reference in new issue
Block a user