Fix initial errors in calculate metrics and get progress working in frontend

This commit is contained in:
2025-01-12 14:12:18 -05:00
parent 3e855eeb2b
commit ac8563325a
3 changed files with 148 additions and 67 deletions

View File

@@ -357,8 +357,8 @@ router.post('/cancel', (req, res) => {
}
try {
// Kill the process
activeImport.kill();
// Kill the process with SIGTERM signal
activeImport.kill('SIGTERM');
// Clean up
activeImport = null;
@@ -383,6 +383,9 @@ router.post('/cancel', (req, res) => {
case 'reset':
sendProgressToClients(resetClients, cancelMessage);
break;
case 'calculate-metrics':
sendProgressToClients(calculateMetricsClients, cancelMessage);
break;
}
res.json({ success: true });
@@ -532,51 +535,98 @@ router.post('/reset-metrics', async (req, res) => {
// Add calculate-metrics endpoint
router.post('/calculate-metrics', async (req, res) => {
if (activeImport) {
res.status(400).json({ error: 'Operation already in progress' });
return;
return res.status(409).json({ error: 'Import already in progress' });
}
try {
// Set active import to prevent concurrent operations
activeImport = {
type: 'calculate-metrics',
status: 'running',
operation: 'Starting metrics calculation'
};
// Send initial response
res.status(200).json({ message: 'Metrics calculation started' });
// Send initial progress through SSE
sendProgressToClients(calculateMetricsClients, {
status: 'running',
operation: 'Starting metrics calculation',
percentage: '0'
const scriptPath = path.join(__dirname, '..', '..', 'scripts', 'calculate-metrics.js');
if (!require('fs').existsSync(scriptPath)) {
return res.status(500).json({ error: 'Calculate metrics script not found' });
}
activeImport = spawn('node', [scriptPath]);
let wasCancelled = false;
activeImport.stdout.on('data', (data) => {
const output = data.toString().trim();
try {
// Try to parse as JSON
const jsonData = JSON.parse(output);
sendProgressToClients(calculateMetricsClients, {
status: 'running',
...jsonData
});
} catch (e) {
// If not JSON, send as plain progress
sendProgressToClients(calculateMetricsClients, {
status: 'running',
progress: output
});
}
});
// Run the metrics calculation script
const calculateMetrics = require('../../scripts/calculate-metrics');
await calculateMetrics();
// Send completion through SSE
sendProgressToClients(calculateMetricsClients, {
status: 'complete',
operation: 'Metrics calculation completed',
percentage: '100'
activeImport.stderr.on('data', (data) => {
if (wasCancelled) return; // Don't send errors if cancelled
const error = data.toString().trim();
try {
// Try to parse as JSON
const jsonData = JSON.parse(error);
sendProgressToClients(calculateMetricsClients, {
status: 'error',
...jsonData
});
} catch {
sendProgressToClients(calculateMetricsClients, {
status: 'error',
error
});
}
});
activeImport = null;
await new Promise((resolve, reject) => {
activeImport.on('close', (code, signal) => {
wasCancelled = signal === 'SIGTERM' || code === 143;
activeImport = null;
importProgress = null;
if (code === 0 || wasCancelled) {
if (wasCancelled) {
sendProgressToClients(calculateMetricsClients, {
status: 'cancelled',
operation: 'Operation cancelled'
});
} else {
sendProgressToClients(calculateMetricsClients, {
status: 'complete',
operation: 'Metrics calculation complete'
});
}
resolve();
} else {
reject(new Error(`Metrics calculation process exited with code ${code}`));
}
});
});
res.json({ success: true });
} catch (error) {
console.error('Error during metrics calculation:', error);
// Send error through SSE
sendProgressToClients(calculateMetricsClients, {
status: 'error',
error: error.message || 'Failed to calculate metrics'
});
console.error('Error calculating metrics:', error);
activeImport = null;
res.status(500).json({ error: error.message || 'Failed to calculate metrics' });
importProgress = null;
// Only send error if it wasn't a cancellation
if (!error.message?.includes('code 143') && !error.message?.includes('SIGTERM')) {
sendProgressToClients(calculateMetricsClients, {
status: 'error',
error: error.message
});
res.status(500).json({ error: 'Failed to calculate metrics', details: error.message });
} else {
res.json({ success: true });
}
}
});