fix(startup): install Ruffle in the background, into the served directory

The server awaited the Ruffle download before listening, so the port stayed
closed for minutes on slow storage and would stay closed indefinitely if the
download stalled. RuffleService also checked frontend/public/ruffle while a
built deployment serves frontend/dist/ruffle, so a fresh container re-downloaded
Ruffle it already shipped.

Install in the background with its own error handling, and target the directory
that is actually served.
This commit is contained in:
Darkraise
2026-08-12 01:14:13 +07:00
parent a470d0a9ef
commit 73d6c3f01c
2 changed files with 35 additions and 17 deletions
+18 -13
View File
@@ -288,20 +288,25 @@ async function startServer() {
logger.warn('Failed to pre-warm filter options cache:', error);
});
try {
const ruffleService = new RuffleService();
if (!ruffleService.verifyInstallation()) {
logger.info('🎮 Ruffle not found, downloading latest version...');
await ruffleService.updateRuffle();
logger.info('✅ Ruffle installation complete');
} else {
const version = ruffleService.getCurrentVersion();
logger.info(`✅ Ruffle verified (version: ${version || 'unknown'})`);
// Ruffle installs in the background: it downloads from GitHub, and awaiting it
// here kept the port closed for minutes on slow storage — indefinitely if the
// download stalled. Flash games need it, everything else does not.
void (async () => {
try {
const ruffleService = new RuffleService();
if (!ruffleService.verifyInstallation()) {
logger.info('🎮 Ruffle not found, downloading latest version...');
await ruffleService.updateRuffle();
logger.info('✅ Ruffle installation complete');
} else {
const version = ruffleService.getCurrentVersion();
logger.info(`✅ Ruffle verified (version: ${version || 'unknown'})`);
}
} catch (error) {
logger.error('Failed to install Ruffle:', error);
logger.warn('⚠️ Continuing without Ruffle - Flash games will not work');
}
} catch (error) {
logger.error('Failed to install Ruffle:', error);
logger.warn('⚠️ Continuing without Ruffle - Flash games will not work');
}
})();
try {
const systemSettings = CachedSystemSettingsService.getInstance();
+17 -4
View File
@@ -5,6 +5,7 @@ import * as path from 'path';
import AdmZip from 'adm-zip';
import { AppError } from '../middleware/errorHandler';
import { logger } from '../utils/logger';
import { config } from '../config';
interface GitHubAsset {
name: string;
@@ -16,7 +17,13 @@ export class RuffleService {
private readonly githubApiUrl = 'https://api.github.com/repos/ruffle-rs/ruffle/releases';
constructor() {
this.frontendPublicPath = path.resolve(__dirname, '../../../frontend/public/ruffle');
// Install into the directory that is actually served. In a built deployment
// that is the frontend's dist output; in development Vite serves public/.
// Pointing at public/ in a container made every fresh start re-download
// Ruffle even though the image already ships it in dist/.
this.frontendPublicPath = config.serveFrontend
? path.join(config.frontendDistPath, 'ruffle')
: path.resolve(__dirname, '../../../frontend/public/ruffle');
}
/**
@@ -146,7 +153,9 @@ export class RuffleService {
}
const normalizedCurrent = this.normalizeVersion(currentVersion);
logger.debug(`[RuffleService] Current version: ${currentVersion} -> normalized: ${normalizedCurrent}`);
logger.debug(
`[RuffleService] Current version: ${currentVersion} -> normalized: ${normalizedCurrent}`
);
// Filter releases that have web-selfhosted.zip and are newer than current version
const newerReleases = releases.filter((release) => {
@@ -162,11 +171,15 @@ export class RuffleService {
// Must be newer than current version
const releaseVersion = this.normalizeVersion(release.tag_name);
const isNewer = releaseVersion > normalizedCurrent;
logger.debug(`[RuffleService] Release ${release.tag_name} -> ${releaseVersion}, isNewer: ${isNewer}`);
logger.debug(
`[RuffleService] Release ${release.tag_name} -> ${releaseVersion}, isNewer: ${isNewer}`
);
return isNewer;
});
logger.info(`[RuffleService] Found ${newerReleases.length} releases newer than ${normalizedCurrent}`);
logger.info(
`[RuffleService] Found ${newerReleases.length} releases newer than ${normalizedCurrent}`
);
if (newerReleases.length === 0) {
return releases[0]?.body || 'No changelog available.';