fix(content): implement state refresh on update to prevent data loss on tab switch
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
|
||||
const express = require('express');
|
||||
const { spawn } = require('child_process');
|
||||
const path = require('path');
|
||||
@@ -6,21 +7,63 @@ const fs = require('fs');
|
||||
const app = express();
|
||||
const port = process.env.PORT || 3006;
|
||||
|
||||
// LOGGING SETUP
|
||||
const LOG_DIR = '/app/Log_from_docker';
|
||||
if (!fs.existsSync(LOG_DIR)) {
|
||||
try {
|
||||
fs.mkdirSync(LOG_DIR, { recursive: true });
|
||||
} catch (e) {
|
||||
console.error("Could not create Log directory:", e);
|
||||
}
|
||||
}
|
||||
const LOG_FILE = path.join(LOG_DIR, 'content_node_server.log');
|
||||
|
||||
function log(message, level = 'INFO') {
|
||||
const timestamp = new Date().toISOString();
|
||||
const logLine = `[${timestamp}] [${level}] ${message}\n`;
|
||||
|
||||
// Console output
|
||||
if (level === 'ERROR') console.error(logLine);
|
||||
else console.log(logLine);
|
||||
|
||||
// File output
|
||||
try {
|
||||
fs.appendFileSync(LOG_FILE, logLine);
|
||||
} catch (e) {
|
||||
console.error("Failed to write to log file:", e);
|
||||
}
|
||||
}
|
||||
|
||||
app.use(express.json({ limit: '50mb' }));
|
||||
|
||||
// INITIALIZE DATABASE ON START
|
||||
const dbScript = path.join(__dirname, 'content_db_manager.py');
|
||||
console.log("Initializing database...");
|
||||
spawn('python3', [dbScript]);
|
||||
log(`Initializing database via ${dbScript}...`);
|
||||
const dbInit = spawn('python3', [dbScript]);
|
||||
|
||||
dbInit.stdout.on('data', (data) => log(`DB Init Output: ${data}`));
|
||||
dbInit.stderr.on('data', (data) => log(`DB Init Error: ${data}`, 'ERROR'));
|
||||
dbInit.on('close', (code) => log(`DB Init finished with code ${code}`));
|
||||
|
||||
|
||||
// Helper to run python commands
|
||||
function runPython(mode, payload) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const payloadFile = path.join(__dirname, `payload_${Date.now()}.json`);
|
||||
fs.writeFileSync(payloadFile, JSON.stringify(payload));
|
||||
|
||||
try {
|
||||
fs.writeFileSync(payloadFile, JSON.stringify(payload));
|
||||
log(`Created payload file: ${payloadFile} for mode: ${mode}`);
|
||||
} catch (e) {
|
||||
log(`Failed to write payload file: ${e.message}`, 'ERROR');
|
||||
return reject(e);
|
||||
}
|
||||
|
||||
const scriptPath = path.join(__dirname, 'content_orchestrator.py');
|
||||
log(`Spawning Python: python3 ${scriptPath} --mode ${mode} --payload_file ${payloadFile}`);
|
||||
|
||||
const pythonProcess = spawn('python3', [
|
||||
path.join(__dirname, 'content_orchestrator.py'),
|
||||
scriptPath,
|
||||
'--mode', mode,
|
||||
'--payload_file', payloadFile
|
||||
]);
|
||||
@@ -28,18 +71,40 @@ function runPython(mode, payload) {
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
|
||||
pythonProcess.stdout.on('data', (data) => stdout += data.toString());
|
||||
pythonProcess.stderr.on('data', (data) => stderr += data.toString());
|
||||
pythonProcess.stdout.on('data', (data) => {
|
||||
stdout += data.toString();
|
||||
});
|
||||
|
||||
pythonProcess.stderr.on('data', (data) => {
|
||||
stderr += data.toString();
|
||||
});
|
||||
|
||||
pythonProcess.on('close', (code) => {
|
||||
if (fs.existsSync(payloadFile)) fs.unlinkSync(payloadFile);
|
||||
if (code !== 0) {
|
||||
console.error(`Python error (code ${code}):`, stderr);
|
||||
return reject(stderr);
|
||||
// Cleanup payload file
|
||||
if (fs.existsSync(payloadFile)) {
|
||||
try {
|
||||
fs.unlinkSync(payloadFile);
|
||||
} catch(e) {
|
||||
log(`Warning: Could not delete payload file: ${e.message}`, 'WARN');
|
||||
}
|
||||
}
|
||||
|
||||
if (code !== 0) {
|
||||
log(`Python script exited with code ${code}. Stderr: ${stderr}`, 'ERROR');
|
||||
return reject(stderr || "Unknown Python Error");
|
||||
}
|
||||
|
||||
// Log stderr anyway as it might contain debug info (Python logging often goes to stderr)
|
||||
if (stderr) {
|
||||
log(`Python Stderr (Debug): ${stderr}`);
|
||||
}
|
||||
|
||||
try {
|
||||
resolve(JSON.parse(stdout));
|
||||
log(`Python Stdout received (${stdout.length} bytes). Parsing JSON...`);
|
||||
const parsed = JSON.parse(stdout);
|
||||
resolve(parsed);
|
||||
} catch (e) {
|
||||
log(`Failed to parse JSON output: ${stdout.substring(0, 200)}...`, 'ERROR');
|
||||
reject("Failed to parse Python output: " + stdout);
|
||||
}
|
||||
});
|
||||
@@ -47,15 +112,19 @@ function runPython(mode, payload) {
|
||||
}
|
||||
|
||||
app.post('/api/:mode', async (req, res) => {
|
||||
const mode = req.params.mode;
|
||||
log(`Incoming POST request for mode: ${mode}`);
|
||||
try {
|
||||
const result = await runPython(req.params.mode, req.body);
|
||||
const result = await runPython(mode, req.body);
|
||||
log(`Request for ${mode} completed successfully.`);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
log(`Request for ${mode} failed: ${error}`, 'ERROR');
|
||||
res.status(500).json({ error: error.toString() });
|
||||
}
|
||||
});
|
||||
|
||||
// Serve static assets from build (for production)
|
||||
// Serve static assets
|
||||
if (fs.existsSync(path.join(__dirname, 'dist'))) {
|
||||
app.use(express.static(path.join(__dirname, 'dist')));
|
||||
app.get('*', (req, res) => {
|
||||
@@ -64,5 +133,5 @@ if (fs.existsSync(path.join(__dirname, 'dist'))) {
|
||||
}
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Content Engine Server running on port ${port}`);
|
||||
});
|
||||
log(`Content Engine Server running on port ${port}`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user