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:
parent
a490e14126
commit
f50b609a36
11 changed files with 97 additions and 69 deletions
|
|
@ -277,12 +277,16 @@ export function usePublicationData() {
|
|||
|
||||
// --- Run-triggered refresh watcher ---
|
||||
|
||||
let previousRunStatusKey: string | null = null;
|
||||
|
||||
watch(
|
||||
() => runStatus.latestRun,
|
||||
async (nextRun, previousRun) => {
|
||||
const nextRunId = nextRun && (nextRun.status === "running" || nextRun.status === "resolving") ? nextRun.id : null;
|
||||
const previousRunId = previousRun && (previousRun.status === "running" || previousRun.status === "resolving") ? previousRun.id : null;
|
||||
if (nextRunId === null || nextRunId === previousRunId) return;
|
||||
async (nextRun) => {
|
||||
const nextStatus = nextRun ? `${nextRun.id}:${nextRun.status}` : null;
|
||||
if (nextStatus === previousRunStatusKey) return;
|
||||
previousRunStatusKey = nextStatus;
|
||||
const isActive = nextRun && (nextRun.status === "running" || nextRun.status === "resolving");
|
||||
if (!isActive) return;
|
||||
resetPageAndSnapshot();
|
||||
await loadPublications();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
import { type PublicationItem } from "@/features/publications";
|
||||
import { ApiRequestError } from "@/lib/api/errors";
|
||||
|
||||
export const RUN_STATUS_POLL_INTERVAL_MS = 5000;
|
||||
export const RUN_STATUS_POLL_INTERVAL_MS = 15000;
|
||||
export const RUN_STATUS_STARTING_PHASE_MS = 1500;
|
||||
|
||||
export type StartManualCheckResult =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue