fix: bound durable background job retention
This commit is contained in:
parent
e234a6e9a3
commit
c79a2efaab
@ -40,6 +40,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
|
|||||||
- **Durable Background Job Metadata.** Transcription, voice design, casting, and consistent-image jobs now persist
|
- **Durable Background Job Metadata.** Transcription, voice design, casting, and consistent-image jobs now persist
|
||||||
bounded status metadata in SQLite; unfinished jobs are reported as interrupted after a server restart, while prompts,
|
bounded status metadata in SQLite; unfinished jobs are reported as interrupted after a server restart, while prompts,
|
||||||
secrets, audio, and image payloads are excluded from persistence.
|
secrets, audio, and image payloads are excluded from persistence.
|
||||||
|
- **Bounded Durable Job Retention.** Completed background-job metadata is pruned oldest-first at a fixed limit so
|
||||||
|
restart-safe status tracking cannot become an unbounded database growth path.
|
||||||
- **STT Cancellation Safety.** Queued transcription cancels before consuming the single STT slot, and timed-out
|
- **STT Cancellation Safety.** Queued transcription cancels before consuming the single STT slot, and timed-out
|
||||||
requests keep the device slot held until the underlying worker actually exits.
|
requests keep the device slot held until the underlying worker actually exits.
|
||||||
- **Credential Boundary Review.** Provider credentials are now documented as server-only; only the explicitly
|
- **Credential Boundary Review.** Provider credentials are now documented as server-only; only the explicitly
|
||||||
|
|||||||
@ -254,6 +254,11 @@ def background_job_create(job_id: str, kind: str, *, fingerprint: str = "", crea
|
|||||||
"VALUES (?,?,?,?,?,?,?,?,?,?,?)",
|
"VALUES (?,?,?,?,?,?,?,?,?,?,?)",
|
||||||
(str(job_id), str(kind)[:80], "queued", "Queued", 0, 0, None, None, str(fingerprint)[:128], now, now),
|
(str(job_id), str(kind)[:80], "queued", "Queued", 0, 0, None, None, str(fingerprint)[:128], now, now),
|
||||||
)
|
)
|
||||||
|
conn.execute(
|
||||||
|
"DELETE FROM background_jobs WHERE job_id IN ("
|
||||||
|
"SELECT job_id FROM background_jobs WHERE done=1 ORDER BY updated ASC "
|
||||||
|
"LIMIT -1 OFFSET 255)"
|
||||||
|
)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -194,6 +194,22 @@ class SecurityValidationTests(unittest.TestCase):
|
|||||||
conn.execute("DELETE FROM background_jobs WHERE job_id=?", (job_id,))
|
conn.execute("DELETE FROM background_jobs WHERE job_id=?", (job_id,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
def test_background_job_persistence_prunes_old_completed_rows(self):
|
||||||
|
from core.database import _open, background_job_create, background_job_update
|
||||||
|
prefix = "prune-job-"
|
||||||
|
try:
|
||||||
|
for index in range(260):
|
||||||
|
job_id = prefix + str(index)
|
||||||
|
background_job_create(job_id, "test")
|
||||||
|
background_job_update(job_id, stage="done", done=True)
|
||||||
|
with _open() as conn:
|
||||||
|
count = conn.execute("SELECT COUNT(*) FROM background_jobs WHERE job_id LIKE ?", (prefix + "%",)).fetchone()[0]
|
||||||
|
self.assertLessEqual(count, 256)
|
||||||
|
finally:
|
||||||
|
with _open() as conn:
|
||||||
|
conn.execute("DELETE FROM background_jobs WHERE job_id LIKE ?", (prefix + "%",))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
def test_fish_cache_eviction_is_bounded(self):
|
def test_fish_cache_eviction_is_bounded(self):
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user