mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-07-07 13:08:54 -07:00
fix(stats): start stats server on background app launch (#144)
This commit is contained in:
@@ -374,6 +374,46 @@ test('handleCliCommand processes --start for second-instance when overlay runtim
|
||||
);
|
||||
});
|
||||
|
||||
test('handleCliCommand ensures background stats server for initial --start --background', () => {
|
||||
const ensured: number[] = [];
|
||||
const { deps } = createDeps({
|
||||
ensureBackgroundStatsServer: () => {
|
||||
ensured.push(1);
|
||||
},
|
||||
});
|
||||
|
||||
handleCliCommand(makeArgs({ start: true, background: true }), 'initial', deps);
|
||||
|
||||
assert.equal(ensured.length, 1);
|
||||
});
|
||||
|
||||
test('handleCliCommand ensures background stats server for second-instance --start --background', () => {
|
||||
const ensured: number[] = [];
|
||||
const { deps } = createDeps({
|
||||
isOverlayRuntimeInitialized: () => true,
|
||||
ensureBackgroundStatsServer: () => {
|
||||
ensured.push(1);
|
||||
},
|
||||
});
|
||||
|
||||
handleCliCommand(makeArgs({ start: true, background: true }), 'second-instance', deps);
|
||||
|
||||
assert.equal(ensured.length, 1);
|
||||
});
|
||||
|
||||
test('handleCliCommand does not ensure background stats server for foreground --start', () => {
|
||||
const ensured: number[] = [];
|
||||
const { deps } = createDeps({
|
||||
ensureBackgroundStatsServer: () => {
|
||||
ensured.push(1);
|
||||
},
|
||||
});
|
||||
|
||||
handleCliCommand(makeArgs({ start: true }), 'initial', deps);
|
||||
|
||||
assert.equal(ensured.length, 0);
|
||||
});
|
||||
|
||||
test('handleCliCommand forces setup open for second-instance setup command', () => {
|
||||
const { deps, calls } = createDeps();
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ export interface CliCommandServiceDeps {
|
||||
mode: NonNullable<CliArgs['youtubeMode']>;
|
||||
source: CliCommandSource;
|
||||
}) => Promise<void>;
|
||||
ensureBackgroundStatsServer?: () => void;
|
||||
printHelp: () => void;
|
||||
hasMainWindow: () => boolean;
|
||||
getMultiCopyTimeoutMs: () => number;
|
||||
@@ -185,6 +186,7 @@ interface AnilistCliRuntime {
|
||||
interface AppCliRuntime {
|
||||
stop: () => void;
|
||||
hasMainWindow: () => boolean;
|
||||
ensureBackgroundStatsServer?: () => void;
|
||||
runUpdateCommand: CliCommandServiceDeps['runUpdateCommand'];
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: CliCommandServiceDeps['runEnsureLinuxRuntimePluginAssetsCommand'];
|
||||
runYoutubePlaybackFlow: CliCommandServiceDeps['runYoutubePlaybackFlow'];
|
||||
@@ -299,6 +301,7 @@ export function createCliCommandDepsRuntime(
|
||||
runUpdateCommand: options.app.runUpdateCommand,
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: options.app.runEnsureLinuxRuntimePluginAssetsCommand,
|
||||
runYoutubePlaybackFlow: options.app.runYoutubePlaybackFlow,
|
||||
ensureBackgroundStatsServer: options.app.ensureBackgroundStatsServer,
|
||||
printHelp: options.ui.printHelp,
|
||||
hasMainWindow: options.app.hasMainWindow,
|
||||
getMultiCopyTimeoutMs: options.getMultiCopyTimeoutMs,
|
||||
@@ -393,6 +396,10 @@ export function handleCliCommand(
|
||||
deps.log(`Starting MPV IPC connection on socket: ${socketPath}`);
|
||||
}
|
||||
|
||||
if (args.start && args.background) {
|
||||
deps.ensureBackgroundStatsServer?.();
|
||||
}
|
||||
|
||||
if (args.sessionAction) {
|
||||
dispatchCliSessionAction(
|
||||
args.sessionAction,
|
||||
|
||||
+10
@@ -37,6 +37,7 @@ import { createAniSkipRuntime } from './main/runtime/aniskip-runtime';
|
||||
import { resolveAniSkipMetadataForFile } from './main/runtime/aniskip-metadata';
|
||||
import { createDiscordRpcClient } from './main/runtime/discord-rpc-client.js';
|
||||
import { startAppControlServer } from './main/runtime/app-control-server';
|
||||
import { createEnsureBackgroundStatsServerHandler } from './main/runtime/background-stats-startup';
|
||||
import {
|
||||
markJellyfinRemotePlaybackLoaded as markJellyfinRemotePlaybackLoadedState,
|
||||
shouldAutoLoadSecondarySubTrackForJellyfinPlayback,
|
||||
@@ -4069,6 +4070,14 @@ const statsStartupRuntime = {
|
||||
}
|
||||
},
|
||||
} as const;
|
||||
const ensureBackgroundStatsServer = createEnsureBackgroundStatsServerHandler({
|
||||
isStatsAutoStartEnabled: () => getResolvedConfig().stats.autoStartServer,
|
||||
isImmersionTrackingEnabled: () => getResolvedConfig().immersionTracking?.enabled !== false,
|
||||
ensureBackgroundStatsServerStarted: () =>
|
||||
statsStartupRuntime.ensureBackgroundStatsServerStarted(),
|
||||
logInfo: (message) => logger.info(message),
|
||||
logWarn: (message, error) => logger.warn(message, error),
|
||||
});
|
||||
|
||||
const runStatsCliCommand = createRunStatsCliCommandHandler({
|
||||
getResolvedConfig: () => getResolvedConfig(),
|
||||
@@ -5965,6 +5974,7 @@ const { handleCliCommand, handleInitialArgs } = composeCliStartupHandlers({
|
||||
);
|
||||
},
|
||||
runYoutubePlaybackFlow: (request) => youtubePlaybackRuntime.runYoutubePlaybackFlow(request),
|
||||
ensureBackgroundStatsServer: () => ensureBackgroundStatsServer(),
|
||||
openYomitanSettings: () => openYomitanSettings(),
|
||||
openConfigSettingsWindow: () => openConfigSettingsWindow(),
|
||||
cycleSecondarySubMode: () => handleCycleSecondarySubMode(),
|
||||
|
||||
@@ -47,6 +47,7 @@ export interface CliCommandRuntimeServiceContext {
|
||||
runUpdateCommand: CliCommandRuntimeServiceDepsParams['app']['runUpdateCommand'];
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: CliCommandRuntimeServiceDepsParams['app']['runEnsureLinuxRuntimePluginAssetsCommand'];
|
||||
runYoutubePlaybackFlow: CliCommandRuntimeServiceDepsParams['app']['runYoutubePlaybackFlow'];
|
||||
ensureBackgroundStatsServer?: CliCommandRuntimeServiceDepsParams['app']['ensureBackgroundStatsServer'];
|
||||
openYomitanSettings: () => void;
|
||||
openConfigSettingsWindow: () => void;
|
||||
cycleSecondarySubMode: () => void;
|
||||
@@ -124,6 +125,7 @@ function createCliCommandDepsFromContext(
|
||||
app: {
|
||||
stop: context.stopApp,
|
||||
hasMainWindow: context.hasMainWindow,
|
||||
ensureBackgroundStatsServer: context.ensureBackgroundStatsServer,
|
||||
runUpdateCommand: context.runUpdateCommand,
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: context.runEnsureLinuxRuntimePluginAssetsCommand,
|
||||
runYoutubePlaybackFlow: context.runYoutubePlaybackFlow,
|
||||
|
||||
@@ -200,6 +200,7 @@ export interface CliCommandRuntimeServiceDepsParams {
|
||||
app: {
|
||||
stop: CliCommandDepsRuntimeOptions['app']['stop'];
|
||||
hasMainWindow: CliCommandDepsRuntimeOptions['app']['hasMainWindow'];
|
||||
ensureBackgroundStatsServer?: CliCommandDepsRuntimeOptions['app']['ensureBackgroundStatsServer'];
|
||||
runUpdateCommand: CliCommandDepsRuntimeOptions['app']['runUpdateCommand'];
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: CliCommandDepsRuntimeOptions['app']['runEnsureLinuxRuntimePluginAssetsCommand'];
|
||||
runYoutubePlaybackFlow: CliCommandDepsRuntimeOptions['app']['runYoutubePlaybackFlow'];
|
||||
@@ -402,6 +403,7 @@ export function createCliCommandRuntimeServiceDeps(
|
||||
app: {
|
||||
stop: params.app.stop,
|
||||
hasMainWindow: params.app.hasMainWindow,
|
||||
ensureBackgroundStatsServer: params.app.ensureBackgroundStatsServer,
|
||||
runUpdateCommand: params.app.runUpdateCommand,
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: params.app.runEnsureLinuxRuntimePluginAssetsCommand,
|
||||
runYoutubePlaybackFlow: params.app.runYoutubePlaybackFlow,
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { createEnsureBackgroundStatsServerHandler } from './background-stats-startup';
|
||||
|
||||
function createDeps(
|
||||
overrides: Partial<Parameters<typeof createEnsureBackgroundStatsServerHandler>[0]> = {},
|
||||
) {
|
||||
const calls: string[] = [];
|
||||
const deps: Parameters<typeof createEnsureBackgroundStatsServerHandler>[0] = {
|
||||
isStatsAutoStartEnabled: () => true,
|
||||
isImmersionTrackingEnabled: () => true,
|
||||
ensureBackgroundStatsServerStarted: () => {
|
||||
calls.push('ensureBackgroundStatsServerStarted');
|
||||
return { url: 'http://127.0.0.1:3888', runningInCurrentProcess: true };
|
||||
},
|
||||
logInfo: (message) => {
|
||||
calls.push(`info:${message}`);
|
||||
},
|
||||
logWarn: (message) => {
|
||||
calls.push(`warn:${message}`);
|
||||
},
|
||||
...overrides,
|
||||
};
|
||||
return { deps, calls };
|
||||
}
|
||||
|
||||
test('ensures background stats server and logs local startup', () => {
|
||||
const { deps, calls } = createDeps();
|
||||
|
||||
createEnsureBackgroundStatsServerHandler(deps)();
|
||||
|
||||
assert.ok(calls.includes('ensureBackgroundStatsServerStarted'));
|
||||
assert.ok(
|
||||
calls.some((value) => value.startsWith('info:') && value.includes('http://127.0.0.1:3888')),
|
||||
);
|
||||
});
|
||||
|
||||
test('logs reuse when a background stats server is already running', () => {
|
||||
const { deps, calls } = createDeps({
|
||||
ensureBackgroundStatsServerStarted: () => ({
|
||||
url: 'http://127.0.0.1:3888',
|
||||
runningInCurrentProcess: false,
|
||||
}),
|
||||
});
|
||||
|
||||
createEnsureBackgroundStatsServerHandler(deps)();
|
||||
|
||||
assert.ok(
|
||||
calls.some((value) => value.startsWith('info:') && /already running|reusing/i.test(value)),
|
||||
);
|
||||
});
|
||||
|
||||
test('skips when stats.autoStartServer is disabled', () => {
|
||||
const { deps, calls } = createDeps({ isStatsAutoStartEnabled: () => false });
|
||||
|
||||
createEnsureBackgroundStatsServerHandler(deps)();
|
||||
|
||||
assert.equal(calls.includes('ensureBackgroundStatsServerStarted'), false);
|
||||
});
|
||||
|
||||
test('skips when immersion tracking is disabled', () => {
|
||||
const { deps, calls } = createDeps({ isImmersionTrackingEnabled: () => false });
|
||||
|
||||
createEnsureBackgroundStatsServerHandler(deps)();
|
||||
|
||||
assert.equal(calls.includes('ensureBackgroundStatsServerStarted'), false);
|
||||
});
|
||||
|
||||
test('logs a warning instead of throwing when startup fails', () => {
|
||||
const { deps, calls } = createDeps({
|
||||
ensureBackgroundStatsServerStarted: () => {
|
||||
throw new Error('port in use');
|
||||
},
|
||||
});
|
||||
|
||||
assert.doesNotThrow(() => createEnsureBackgroundStatsServerHandler(deps)());
|
||||
assert.ok(calls.some((value) => value.startsWith('warn:')));
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
export interface EnsureBackgroundStatsServerDeps {
|
||||
isStatsAutoStartEnabled: () => boolean;
|
||||
isImmersionTrackingEnabled: () => boolean;
|
||||
ensureBackgroundStatsServerStarted: () => {
|
||||
url: string;
|
||||
runningInCurrentProcess: boolean;
|
||||
};
|
||||
logInfo: (message: string) => void;
|
||||
logWarn: (message: string, error?: unknown) => void;
|
||||
}
|
||||
|
||||
export function createEnsureBackgroundStatsServerHandler(
|
||||
deps: EnsureBackgroundStatsServerDeps,
|
||||
): () => void {
|
||||
return () => {
|
||||
if (!deps.isStatsAutoStartEnabled()) {
|
||||
deps.logInfo('Background start: stats.autoStartServer is disabled; skipping stats server.');
|
||||
return;
|
||||
}
|
||||
if (!deps.isImmersionTrackingEnabled()) {
|
||||
deps.logInfo('Background start: immersion tracking is disabled; skipping stats server.');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const result = deps.ensureBackgroundStatsServerStarted();
|
||||
deps.logInfo(
|
||||
result.runningInCurrentProcess
|
||||
? `Background start: stats server started at ${result.url}.`
|
||||
: `Background start: stats server already running at ${result.url}; skipping.`,
|
||||
);
|
||||
} catch (error) {
|
||||
deps.logWarn('Background start: failed to start stats server.', error);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -45,6 +45,7 @@ export function createBuildCliCommandContextDepsHandler(deps: {
|
||||
runUpdateCommand: CliCommandContextFactoryDeps['runUpdateCommand'];
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: CliCommandContextFactoryDeps['runEnsureLinuxRuntimePluginAssetsCommand'];
|
||||
runYoutubePlaybackFlow: CliCommandContextFactoryDeps['runYoutubePlaybackFlow'];
|
||||
ensureBackgroundStatsServer?: CliCommandContextFactoryDeps['ensureBackgroundStatsServer'];
|
||||
openYomitanSettings: () => void;
|
||||
openConfigSettingsWindow: () => void;
|
||||
cycleSecondarySubMode: () => void;
|
||||
@@ -103,6 +104,7 @@ export function createBuildCliCommandContextDepsHandler(deps: {
|
||||
runUpdateCommand: deps.runUpdateCommand,
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: deps.runEnsureLinuxRuntimePluginAssetsCommand,
|
||||
runYoutubePlaybackFlow: deps.runYoutubePlaybackFlow,
|
||||
ensureBackgroundStatsServer: deps.ensureBackgroundStatsServer,
|
||||
openYomitanSettings: deps.openYomitanSettings,
|
||||
openConfigSettingsWindow: deps.openConfigSettingsWindow,
|
||||
cycleSecondarySubMode: deps.cycleSecondarySubMode,
|
||||
|
||||
@@ -61,6 +61,7 @@ export function createBuildCliCommandContextMainDepsHandler(deps: {
|
||||
source: CliCommandSource,
|
||||
) => Promise<void>;
|
||||
runYoutubePlaybackFlow: CliCommandContextFactoryDeps['runYoutubePlaybackFlow'];
|
||||
ensureBackgroundStatsServer?: CliCommandContextFactoryDeps['ensureBackgroundStatsServer'];
|
||||
|
||||
openYomitanSettings: () => void;
|
||||
openConfigSettingsWindow: () => void;
|
||||
@@ -140,6 +141,7 @@ export function createBuildCliCommandContextMainDepsHandler(deps: {
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: (args: CliArgs, source: CliCommandSource) =>
|
||||
deps.runEnsureLinuxRuntimePluginAssetsCommand(args, source),
|
||||
runYoutubePlaybackFlow: (request) => deps.runYoutubePlaybackFlow(request),
|
||||
ensureBackgroundStatsServer: deps.ensureBackgroundStatsServer,
|
||||
openYomitanSettings: () => deps.openYomitanSettings(),
|
||||
openConfigSettingsWindow: () => deps.openConfigSettingsWindow(),
|
||||
cycleSecondarySubMode: () => deps.cycleSecondarySubMode(),
|
||||
|
||||
@@ -50,6 +50,7 @@ export type CliCommandContextFactoryDeps = {
|
||||
runUpdateCommand: CliCommandRuntimeServiceContext['runUpdateCommand'];
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: CliCommandRuntimeServiceContext['runEnsureLinuxRuntimePluginAssetsCommand'];
|
||||
runYoutubePlaybackFlow: CliCommandRuntimeServiceContext['runYoutubePlaybackFlow'];
|
||||
ensureBackgroundStatsServer?: CliCommandRuntimeServiceContext['ensureBackgroundStatsServer'];
|
||||
openYomitanSettings: () => void;
|
||||
openConfigSettingsWindow: () => void;
|
||||
cycleSecondarySubMode: () => void;
|
||||
@@ -130,6 +131,7 @@ export function createCliCommandContext(
|
||||
runUpdateCommand: deps.runUpdateCommand,
|
||||
runEnsureLinuxRuntimePluginAssetsCommand: deps.runEnsureLinuxRuntimePluginAssetsCommand,
|
||||
runYoutubePlaybackFlow: deps.runYoutubePlaybackFlow,
|
||||
ensureBackgroundStatsServer: deps.ensureBackgroundStatsServer,
|
||||
openYomitanSettings: deps.openYomitanSettings,
|
||||
openConfigSettingsWindow: deps.openConfigSettingsWindow,
|
||||
cycleSecondarySubMode: deps.cycleSecondarySubMode,
|
||||
|
||||
Reference in New Issue
Block a user