fix(db,frontend): reserve DB connections for API and reduce frontend polling

Background tasks (ingestion, PDF resolution, scheduler) now acquire an
asyncio.Semaphore before checking out a DB connection, guaranteeing at
least N connections remain available for API request handlers. Removes
duplicate polling loop from PublicationsPage, debounces publication
reload on run-status changes, and increases poll interval from 5s to 15s
since SSE handles live discovery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Justin Visser 2026-03-02 19:09:06 +01:00
parent a490e14126
commit f50b609a36
11 changed files with 97 additions and 69 deletions

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import { computed, onMounted, ref, watch } from "vue";
import AppPage from "@/components/layout/AppPage.vue";
import AsyncStateGate from "@/components/patterns/AsyncStateGate.vue";
@ -37,23 +37,6 @@ const selectedPublicationKeys = ref<Set<string>>(new Set());
const retryingPublicationKeys = ref<Set<string>>(new Set());
const favoriteUpdatingKeys = ref<Set<string>>(new Set());
const PUBLICATIONS_RUN_STATUS_SYNC_INTERVAL_MS = 5000;
let runStatusSyncTimer: ReturnType<typeof setInterval> | null = null;
function startRunStatusSyncLoop(): void {
if (runStatusSyncTimer !== null) return;
runStatusSyncTimer = setInterval(() => {
if (runStatus.isRunActive) return;
void runStatus.syncLatest();
}, PUBLICATIONS_RUN_STATUS_SYNC_INTERVAL_MS);
}
function stopRunStatusSyncLoop(): void {
if (runStatusSyncTimer === null) return;
clearInterval(runStatusSyncTimer);
runStatusSyncTimer = null;
}
// --- Computed ---
const selectedCount = computed(() => selectedPublicationKeys.value.size);
@ -358,13 +341,8 @@ async function onStartRun(): Promise<void> {
onMounted(() => {
pub.syncFiltersFromRoute();
startRunStatusSyncLoop();
void Promise.all([pub.loadScholarFilters(), pub.loadPublications(), runStatus.syncLatest()]);
});
onUnmounted(() => {
stopRunStatusSyncLoop();
});
</script>
<template>