Compare commits

..

1 Commits

Author SHA1 Message Date
NimBold ac0e288cd8 test(startup): isolate Aria2 WebSocket crash path (#37)
- Issue #37: add a smoke-only switch that stops the Aria2 WebSocket loop.\n- Keep the daemon and poller paths active for a focused delayed-startup comparison.\n\nRefs #37.
2026-08-27 20:01:13 +03:30
3 changed files with 42 additions and 2 deletions
+2 -1
View File
@@ -29,7 +29,8 @@ const child = spawn(executable, [], {
detached: process.platform !== 'win32',
env: {
...process.env,
FIRELINK_SMOKE_TEST: '1',
FIRELINK_SMOKE_TEST: '1',
FIRELINK_DISABLE_ARIA2_WEBSOCKET: '1',
WEBKIT_DISABLE_COMPOSITING_MODE: '1',
GDK_BACKEND: 'x11',
},
+3
View File
@@ -18854,6 +18854,9 @@ pub fn run() {
}
}
if std::env::var_os("FIRELINK_DISABLE_ARIA2_WEBSOCKET").is_some() {
return;
}
let mut ws_retries = 0;
loop {
if ws_retries == 10 {
+37 -1
View File
@@ -15,7 +15,8 @@ import { getCurrentWindow } from '@tauri-apps/api/window';
import { initDownloadListener } from './store/downloadStore';
import {
subscribeToSettingsPersistenceErrors,
useSettingsStore
useSettingsStore,
waitForSettingsPersistence
} from "./store/useSettingsStore";
import { isPermissionGranted, requestPermission, sendNotification } from '@tauri-apps/plugin-notification';
import { WindowControls } from "./components/WindowControls";
@@ -39,7 +40,9 @@ import { changeAppLocale, localeDirection, resolveAppLocale, syncDocumentLocale
import { useTranslation } from 'react-i18next';
import { formatDownloadBytes } from './utils/downloadProgress';
import { synchronizeDocumentAppearance } from './utils/documentAppearance';
import { createMainWindowSizePersistence } from './utils/mainWindowState';
import { createSidebarResizeSession } from './utils/sidebarResize';
import type { MainWindowSize } from './bindings/MainWindowSize';
import {
beginSchedulerControl,
consumeSchedulerHandoffIds,
@@ -491,14 +494,44 @@ function App() {
useEffect(() => {
const disposePersistence = initializeDownloadPersistence(getCurrentWindow().label);
let active = true;
let exitRequested = false;
let exiting = false;
let settingsHydrated = useSettingsStore.persist.hasHydrated();
let latestSizeBeforeHydration: MainWindowSize | null = null;
const unlistenSettingsHydration = settingsHydrated
? null
: useSettingsStore.persist.onFinishHydration(() => {
settingsHydrated = true;
const size = latestSizeBeforeHydration;
latestSizeBeforeHydration = null;
if (size && active && !exitRequested && !exiting) {
useSettingsStore.getState().setMainWindowSize(size);
}
});
const mainWindowSizePersistence = createMainWindowSizePersistence({
appWindow: getCurrentWindow(),
onSize: size => {
if (!active || exiting) return;
if (!settingsHydrated) {
latestSizeBeforeHydration = size;
return;
}
useSettingsStore.getState().setMainWindowSize(size);
}
});
let cleanupListeners: (() => void) | null = null;
let unlistenExit: (() => void) | null = null;
const exitListener = listen('app-exit-requested', async () => {
exitRequested = true;
try {
await mainWindowSizePersistence.flush();
await waitForSettingsPersistence();
await flushDownloadPersistence();
} catch (error) {
console.error('Failed to flush download state before exit:', error);
} finally {
exiting = true;
latestSizeBeforeHydration = null;
await invoke('ack_frontend_exit').catch(error => {
console.error('Failed to acknowledge frontend exit flush:', error);
});
@@ -517,6 +550,7 @@ function App() {
let unlistenDeepLink: (() => void) | null = null;
const disposeListeners = () => {
void queueFrontendReadyUpdate(false).catch(() => {});
mainWindowSizePersistence.dispose();
unlistenExit?.();
unlistenExit = null;
unlistenTerminalState?.();
@@ -722,6 +756,8 @@ function App() {
cleanupListeners = null;
unlistenExit?.();
unlistenExit = null;
unlistenSettingsHydration?.();
mainWindowSizePersistence.dispose();
disposePersistence();
};
}, [addToast, enqueueAddInput, processExtensionDownload, queueFrontendReadyUpdate]);