From f97933bc9bb026cbe5024fd246883a65d428c3f2 Mon Sep 17 00:00:00 2001 From: h Date: Sun, 25 Jan 2026 16:52:15 +0100 Subject: [PATCH] fix(backend): add async lock to prevent Already borrowed issue --- backend/src/utils/convex/client.py | 10 +++++++--- frontend/src/routes/+layout.svelte | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/backend/src/utils/convex/client.py b/backend/src/utils/convex/client.py index 90b655d..731aba1 100644 --- a/backend/src/utils/convex/client.py +++ b/backend/src/utils/convex/client.py @@ -7,15 +7,19 @@ from convex import ConvexClient as SyncConvexClient class ConvexClient: def __init__(self, url: str) -> None: self._client = SyncConvexClient(url) + self._lock = asyncio.Lock() async def query(self, name: str, args: dict[str, Any] | None = None) -> Any: # noqa: ANN401 - return await asyncio.to_thread(self._client.query, name, args or {}) + async with self._lock: + return await asyncio.to_thread(self._client.query, name, args or {}) async def mutation(self, name: str, args: dict[str, Any] | None = None) -> Any: # noqa: ANN401 - return await asyncio.to_thread(self._client.mutation, name, args or {}) + async with self._lock: + return await asyncio.to_thread(self._client.mutation, name, args or {}) async def action(self, name: str, args: dict[str, Any] | None = None) -> Any: # noqa: ANN401 - return await asyncio.to_thread(self._client.action, name, args or {}) + async with self._lock: + return await asyncio.to_thread(self._client.action, name, args or {}) def subscribe(self, name: str, args: dict[str, Any] | None = None) -> Any: # noqa: ANN401 return self._client.subscribe(name, args or {}) diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 61e0a0b..e6dd006 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -2,13 +2,15 @@ import './layout.css'; import favicon from '$lib/assets/favicon.svg'; import { PUBLIC_CONVEX_URL } from '$env/static/public'; + import { env } from '$env/dynamic/public'; import { setupConvex } from 'convex-svelte'; import { hasWebSocketSupport, setupPollingConvex } from '$lib/convex-polling.svelte'; import { setContext } from 'svelte'; let { children } = $props(); - const usePolling = !hasWebSocketSupport(); + const fallbackEnabled = env.PUBLIC_FALLBACK === '1'; + const usePolling = fallbackEnabled && !hasWebSocketSupport(); setContext('convex-use-polling', usePolling); if (usePolling) {