mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 03:20:46 +02:00
Desktop: Fallback to local backend if self-hosted server is offline (#5880)
* Adds a fallback mechanism so the desktop app routes tool operations to the local bundled backend when the user's self-hosted Stirling-PDF server goes offline, and disables tools in the UI that aren't supported locally. * `selfHostedServerMonitor.ts` independently polls the self-hosted server every 15s and exposes which tool endpoints are unavailable when it goes offline * `operationRouter.ts` intercepts operations destined for the self-hosted server and reroutes them to the local bundled backend when the monitor reports it offline * `useSelfHostedToolAvailability.ts` feeds the offline tool set into useToolManagement, disabling affected tools in the UI with a selfHostedOffline reason and banner warning - `SelfHostedOfflineBanner `is a dismissable (session-only) gray bar shown at the top of the UI when in self-hosted mode and the server goes offline. It shows:
This commit is contained in:
@@ -1,24 +1,63 @@
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { backendHealthMonitor } from '@app/services/backendHealthMonitor';
|
||||
import { selfHostedServerMonitor } from '@app/services/selfHostedServerMonitor';
|
||||
import { tauriBackendService } from '@app/services/tauriBackendService';
|
||||
import { connectionModeService } from '@app/services/connectionModeService';
|
||||
import type { BackendHealthState } from '@app/types/backendHealth';
|
||||
|
||||
/**
|
||||
* Hook to read the shared backend health monitor state.
|
||||
* All consumers subscribe to a single poller managed by backendHealthMonitor.
|
||||
* Hook to read backend health state for UI (Run button, BackendHealthIndicator).
|
||||
*
|
||||
* backendHealthMonitor tracks the local bundled backend.
|
||||
* selfHostedServerMonitor tracks the remote server in self-hosted mode.
|
||||
*
|
||||
* isOnline logic:
|
||||
* - SaaS mode: true when local backend is healthy
|
||||
* - Self-hosted mode (server online): true (remote is up)
|
||||
* - Self-hosted mode (server offline, local port known): true so the Run button
|
||||
* stays enabled — operationRouter routes supported tools to local
|
||||
* - Self-hosted mode (server offline, local port unknown): false
|
||||
*/
|
||||
export function useBackendHealth() {
|
||||
const [health, setHealth] = useState<BackendHealthState>(() => backendHealthMonitor.getSnapshot());
|
||||
const [serverStatus, setServerStatus] = useState(
|
||||
() => selfHostedServerMonitor.getSnapshot().status
|
||||
);
|
||||
const [localUrl, setLocalUrl] = useState<string | null>(
|
||||
() => tauriBackendService.getBackendUrl()
|
||||
);
|
||||
const [connectionMode, setConnectionMode] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
void connectionModeService.getCurrentMode().then(setConnectionMode);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
return backendHealthMonitor.subscribe(setHealth);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
return selfHostedServerMonitor.subscribe(state => setServerStatus(state.status));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
return tauriBackendService.subscribeToStatus(() => {
|
||||
setLocalUrl(tauriBackendService.getBackendUrl());
|
||||
});
|
||||
}, []);
|
||||
|
||||
const checkHealth = useCallback(async () => {
|
||||
return backendHealthMonitor.checkNow();
|
||||
}, []);
|
||||
|
||||
const isOnline =
|
||||
connectionMode === 'selfhosted'
|
||||
? serverStatus !== 'offline' || !!localUrl
|
||||
: health.isOnline;
|
||||
|
||||
return {
|
||||
...health,
|
||||
isOnline,
|
||||
checkHealth,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user