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:
@@ -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