Optimize metrics import and split off metrics import functions (untested)
This commit is contained in:
@@ -17,6 +17,7 @@ let importProgress = null;
|
||||
const updateClients = new Set();
|
||||
const importClients = new Set();
|
||||
const resetClients = new Set();
|
||||
const resetMetricsClients = new Set();
|
||||
|
||||
// Helper to send progress to specific clients
|
||||
function sendProgressToClients(clients, progress) {
|
||||
@@ -107,6 +108,28 @@ router.get('/reset/progress', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// Add reset-metrics progress endpoint
|
||||
router.get('/reset-metrics/progress', (req, res) => {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/event-stream',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Connection': 'keep-alive',
|
||||
'Access-Control-Allow-Origin': req.headers.origin || '*',
|
||||
'Access-Control-Allow-Credentials': 'true'
|
||||
});
|
||||
|
||||
// Send an initial message to test the connection
|
||||
res.write('data: {"status":"running","operation":"Initializing connection..."}\n\n');
|
||||
|
||||
// Add this client to the reset-metrics set
|
||||
resetMetricsClients.add(res);
|
||||
|
||||
// Remove client when connection closes
|
||||
req.on('close', () => {
|
||||
resetMetricsClients.delete(res);
|
||||
});
|
||||
});
|
||||
|
||||
// Debug endpoint to verify route registration
|
||||
router.get('/test', (req, res) => {
|
||||
console.log('CSV test endpoint hit');
|
||||
@@ -434,4 +457,104 @@ router.post('/reset', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Add reset-metrics endpoint
|
||||
router.post('/reset-metrics', async (req, res) => {
|
||||
if (activeImport) {
|
||||
res.status(400).json({ error: 'Operation already in progress' });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Set active import to prevent concurrent operations
|
||||
activeImport = {
|
||||
type: 'reset-metrics',
|
||||
status: 'running',
|
||||
operation: 'Starting metrics reset'
|
||||
};
|
||||
|
||||
// Send initial response
|
||||
res.status(200).json({ message: 'Reset metrics started' });
|
||||
|
||||
// Send initial progress through SSE
|
||||
sendProgressToClients(resetMetricsClients, {
|
||||
status: 'running',
|
||||
operation: 'Starting metrics reset'
|
||||
});
|
||||
|
||||
// Run the reset metrics script
|
||||
const resetMetrics = require('../../scripts/reset-metrics');
|
||||
await resetMetrics();
|
||||
|
||||
// Send completion through SSE
|
||||
sendProgressToClients(resetMetricsClients, {
|
||||
status: 'complete',
|
||||
operation: 'Metrics reset completed'
|
||||
});
|
||||
|
||||
activeImport = null;
|
||||
} catch (error) {
|
||||
console.error('Error during metrics reset:', error);
|
||||
|
||||
// Send error through SSE
|
||||
sendProgressToClients(resetMetricsClients, {
|
||||
status: 'error',
|
||||
error: error.message || 'Failed to reset metrics'
|
||||
});
|
||||
|
||||
activeImport = null;
|
||||
res.status(500).json({ error: error.message || 'Failed to reset metrics' });
|
||||
}
|
||||
});
|
||||
|
||||
// Add calculate-metrics endpoint
|
||||
router.post('/calculate-metrics', async (req, res) => {
|
||||
if (activeImport) {
|
||||
res.status(400).json({ error: 'Operation already in progress' });
|
||||
return;
|
||||
}
|
||||
|
||||
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(importClients, {
|
||||
status: 'running',
|
||||
operation: 'Starting metrics calculation',
|
||||
percentage: '0'
|
||||
});
|
||||
|
||||
// Run the metrics calculation script
|
||||
const calculateMetrics = require('../../scripts/calculate-metrics');
|
||||
await calculateMetrics();
|
||||
|
||||
// Send completion through SSE
|
||||
sendProgressToClients(importClients, {
|
||||
status: 'complete',
|
||||
operation: 'Metrics calculation completed',
|
||||
percentage: '100'
|
||||
});
|
||||
|
||||
activeImport = null;
|
||||
} catch (error) {
|
||||
console.error('Error during metrics calculation:', error);
|
||||
|
||||
// Send error through SSE
|
||||
sendProgressToClients(importClients, {
|
||||
status: 'error',
|
||||
error: error.message || 'Failed to calculate metrics'
|
||||
});
|
||||
|
||||
activeImport = null;
|
||||
res.status(500).json({ error: error.message || 'Failed to calculate metrics' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,6 +1,8 @@
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const { spawn } = require('child_process');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const express = require('express');
|
||||
const mysql = require('mysql2/promise');
|
||||
const { corsMiddleware, corsErrorHandler } = require('./middleware/cors');
|
||||
const { initPool } = require('./utils/db');
|
||||
@@ -127,6 +129,111 @@ pool.getConnection()
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Initialize client sets for SSE
|
||||
const importClients = new Set();
|
||||
const updateClients = new Set();
|
||||
const resetClients = new Set();
|
||||
const resetMetricsClients = new Set();
|
||||
|
||||
// Helper function to send progress to SSE clients
|
||||
const sendProgressToClients = (clients, data) => {
|
||||
clients.forEach(client => {
|
||||
try {
|
||||
client.write(`data: ${JSON.stringify(data)}\n\n`);
|
||||
} catch (error) {
|
||||
console.error('Error sending SSE update:', error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Setup SSE connection
|
||||
const setupSSE = (req, res) => {
|
||||
const { type } = req.params;
|
||||
|
||||
// Set headers for SSE
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/event-stream',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Connection': 'keep-alive',
|
||||
'Access-Control-Allow-Origin': req.headers.origin || '*',
|
||||
'Access-Control-Allow-Credentials': 'true'
|
||||
});
|
||||
|
||||
// Send initial message
|
||||
res.write('data: {"status":"connected"}\n\n');
|
||||
|
||||
// Add client to appropriate set
|
||||
const clientSet = type === 'import' ? importClients :
|
||||
type === 'update' ? updateClients :
|
||||
type === 'reset' ? resetClients :
|
||||
type === 'reset-metrics' ? resetMetricsClients :
|
||||
null;
|
||||
|
||||
if (clientSet) {
|
||||
clientSet.add(res);
|
||||
|
||||
// Remove client when connection closes
|
||||
req.on('close', () => {
|
||||
clientSet.delete(res);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Update the status endpoint to include reset-metrics
|
||||
app.get('/csv/status', (req, res) => {
|
||||
res.json({
|
||||
active: !!currentOperation,
|
||||
type: currentOperation?.type || null,
|
||||
progress: currentOperation ? {
|
||||
status: currentOperation.status,
|
||||
operation: currentOperation.operation,
|
||||
current: currentOperation.current,
|
||||
total: currentOperation.total,
|
||||
percentage: currentOperation.percentage
|
||||
} : null
|
||||
});
|
||||
});
|
||||
|
||||
// Update progress endpoint mapping
|
||||
app.get('/csv/:type/progress', (req, res) => {
|
||||
const { type } = req.params;
|
||||
if (!['import', 'update', 'reset', 'reset-metrics'].includes(type)) {
|
||||
res.status(400).json({ error: 'Invalid operation type' });
|
||||
return;
|
||||
}
|
||||
|
||||
setupSSE(req, res);
|
||||
});
|
||||
|
||||
// Update the cancel endpoint to handle reset-metrics
|
||||
app.post('/csv/cancel', (req, res) => {
|
||||
const { operation } = req.query;
|
||||
|
||||
if (!currentOperation) {
|
||||
res.status(400).json({ error: 'No operation in progress' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (operation && operation.toLowerCase() !== currentOperation.type) {
|
||||
res.status(400).json({ error: 'Operation type mismatch' });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Handle cancellation based on operation type
|
||||
if (currentOperation.type === 'reset-metrics') {
|
||||
// Reset metrics doesn't need special cleanup
|
||||
currentOperation = null;
|
||||
res.json({ message: 'Reset metrics cancelled' });
|
||||
} else {
|
||||
// ... existing cancellation logic for other operations ...
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during cancellation:', error);
|
||||
res.status(500).json({ error: 'Failed to cancel operation' });
|
||||
}
|
||||
});
|
||||
|
||||
const PORT = process.env.PORT || 3000;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`[Server] Running in ${process.env.NODE_ENV || 'development'} mode on port ${PORT}`);
|
||||
|
||||
Reference in New Issue
Block a user