feat: improve Windows cache management and enhance FastAPI/Next.js logging in the Electron app
This commit is contained in:
parent
52b37335ea
commit
047ddf284e
2 changed files with 67 additions and 13 deletions
|
|
@ -1,6 +1,7 @@
|
|||
require("dotenv").config();
|
||||
import { app, BrowserWindow } from "electron";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { findUnusedPorts, killProcess, setupEnv, setUserConfig } from "./utils";
|
||||
import { startFastApiServer, startNextJsServer } from "./utils/servers";
|
||||
import { ChildProcessByStdio } from "child_process";
|
||||
|
|
@ -16,6 +17,30 @@ var nextjsProcess: any;
|
|||
|
||||
app.commandLine.appendSwitch('gtk-version', '3');
|
||||
|
||||
// Mitigate "Unable to move the cache: Access is denied" on Windows (Chromium disk cache).
|
||||
// Use explicit cache paths and remove stale old_* dirs that cause move failures.
|
||||
if (process.platform === "win32") {
|
||||
const ud = app.getPath("userData");
|
||||
const cacheBase = path.join(ud, "Cache");
|
||||
const gpuCacheBase = path.join(ud, "GPUCache");
|
||||
app.setPath("cache", cacheBase);
|
||||
app.commandLine.appendSwitch("disk-cache-dir", cacheBase);
|
||||
try {
|
||||
[cacheBase, gpuCacheBase].forEach((dir) => {
|
||||
if (fs.existsSync(dir)) {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
if (e.isDirectory() && e.name.startsWith("old_")) {
|
||||
fs.rmSync(path.join(dir, e.name), { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
/* ignore cleanup errors */
|
||||
}
|
||||
}
|
||||
|
||||
const createWindow = () => {
|
||||
win = new BrowserWindow({
|
||||
width: 1280,
|
||||
|
|
|
|||
|
|
@ -24,8 +24,22 @@ export async function startFastApiServer(
|
|||
const binary = process.platform === "win32" ? "fastapi.exe" : "fastapi";
|
||||
command = path.join(directory, binary);
|
||||
args = ["--port", port.toString()];
|
||||
if (!fs.existsSync(command)) {
|
||||
throw new Error(
|
||||
`FastAPI binary not found at ${command}. Rebuild the app for ${process.platform} or run in dev mode.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const safeLog = (data: Buffer | string, logPath: string) => {
|
||||
try {
|
||||
fs.appendFileSync(logPath, data);
|
||||
} catch {
|
||||
/* ignore if logs dir not writable */
|
||||
}
|
||||
};
|
||||
const fastapiLogPath = path.join(logsDir, "fastapi-server.log");
|
||||
|
||||
const fastApiProcess = spawn(
|
||||
command,
|
||||
args,
|
||||
|
|
@ -36,13 +50,16 @@ export async function startFastApiServer(
|
|||
}
|
||||
);
|
||||
fastApiProcess.stdout.on("data", (data: any) => {
|
||||
fs.appendFileSync(path.join(logsDir, "fastapi-server.log"), data);
|
||||
safeLog(data, fastapiLogPath);
|
||||
console.log(`FastAPI: ${data}`);
|
||||
});
|
||||
fastApiProcess.stderr.on("data", (data: any) => {
|
||||
fs.appendFileSync(path.join(logsDir, "fastapi-server.log"), data);
|
||||
safeLog(data, fastapiLogPath);
|
||||
console.error(`FastAPI: ${data}`);
|
||||
});
|
||||
fastApiProcess.on("error", (err) => {
|
||||
safeLog(`Spawn error: ${err.message}\n`, fastapiLogPath);
|
||||
});
|
||||
// Wait for FastAPI server to start
|
||||
await waitForServer(`${localhost}:${port}/docs`);
|
||||
return fastApiProcess;
|
||||
|
|
@ -67,17 +84,25 @@ export async function startNextJsServer(
|
|||
env: { ...process.env, ...env },
|
||||
}
|
||||
);
|
||||
const nextjsLogPath = path.join(logsDir, "nextjs-server.log");
|
||||
const safeNextLog = (d: Buffer | string) => {
|
||||
try {
|
||||
fs.appendFileSync(nextjsLogPath, d);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
};
|
||||
nextjsProcess.stdout.on("data", (data: any) => {
|
||||
fs.appendFileSync(path.join(logsDir, "nextjs-server.log"), data);
|
||||
safeNextLog(data);
|
||||
console.log(`NextJS: ${data}`);
|
||||
});
|
||||
nextjsProcess.stderr.on("data", (data: any) => {
|
||||
fs.appendFileSync(path.join(logsDir, "nextjs-server.log"), data);
|
||||
safeNextLog(data);
|
||||
console.error(`NextJS: ${data}`);
|
||||
});
|
||||
} else {
|
||||
// Start NextJS build server
|
||||
nextjsProcess = startNextjsBuildServer(directory, port);
|
||||
nextjsProcess = await startNextjsBuildServer(directory, port);
|
||||
}
|
||||
|
||||
// Wait for NextJS server to start
|
||||
|
|
@ -85,16 +110,20 @@ export async function startNextJsServer(
|
|||
return nextjsProcess;
|
||||
}
|
||||
|
||||
async function startNextjsBuildServer(directory: string, port: number) {
|
||||
const server = http.createServer((req, res) => {
|
||||
return handler(req, res, {
|
||||
public: directory,
|
||||
cleanUrls: true,
|
||||
function startNextjsBuildServer(directory: string, port: number): Promise<http.Server> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = http.createServer((req, res) => {
|
||||
return handler(req, res, {
|
||||
public: directory,
|
||||
cleanUrls: true,
|
||||
});
|
||||
});
|
||||
server.on("error", reject);
|
||||
server.listen(port, () => {
|
||||
server.off("error", reject);
|
||||
resolve(server);
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(port);
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue