149 lines
4.9 KiB
JavaScript
149 lines
4.9 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Phase 3 Patch Application Script
|
|
* Applies final modifications to server/index.mjs
|
|
*/
|
|
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const indexFile = path.join(__dirname, 'server', 'index.mjs');
|
|
const backupFile = `${indexFile}.backup.${Date.now()}`;
|
|
|
|
console.log('\n🚀 Phase 3 Patch Application');
|
|
console.log('================================\n');
|
|
|
|
try {
|
|
// Step 1: Create backup
|
|
console.log('📦 Creating backup...');
|
|
fs.copyFileSync(indexFile, backupFile);
|
|
console.log(`✅ Backup created: ${backupFile}\n`);
|
|
|
|
// Step 2: Read the file
|
|
console.log('📖 Reading index.mjs...');
|
|
let content = fs.readFileSync(indexFile, 'utf-8');
|
|
console.log('✅ File read successfully\n');
|
|
|
|
// Step 3: Add performance endpoint setup
|
|
console.log('🔧 Adding performance endpoint setup...');
|
|
const performanceEndpointSetup = `// Phase 3: Setup performance monitoring endpoint
|
|
setupPerformanceEndpoint(app, performanceMonitor, metadataCache, meilisearchCircuitBreaker);
|
|
|
|
`;
|
|
|
|
// Insert before "// Créer le répertoire de la voûte"
|
|
content = content.replace(
|
|
'// Créer le répertoire de la voûte s\'il n\'existe pas',
|
|
performanceEndpointSetup + '// Créer le répertoire de la voûte s\'il n\'existe pas'
|
|
);
|
|
console.log('✅ Performance endpoint setup added\n');
|
|
|
|
// Step 4: Update app.listen() for deferred indexing
|
|
console.log('🔧 Updating app.listen() for deferred indexing...');
|
|
|
|
const oldListen = `app.listen(PORT, '0.0.0.0', () => {
|
|
console.log(\`ObsiViewer server running on http://0.0.0.0:\${PORT}\`);
|
|
console.log(\`Vault directory: \${vaultDir}\`);
|
|
});`;
|
|
|
|
const newListen = `// Phase 3: Deferred Meilisearch indexing (non-blocking)
|
|
let indexingState = { inProgress: false, completed: false };
|
|
const scheduleIndexing = async () => {
|
|
if (indexingState.inProgress) return;
|
|
indexingState.inProgress = true;
|
|
|
|
setImmediate(async () => {
|
|
try {
|
|
console.time('[Meilisearch] Background indexing');
|
|
await fullReindex(vaultDir);
|
|
console.timeEnd('[Meilisearch] Background indexing');
|
|
indexingState.completed = true;
|
|
console.log('[Meilisearch] ✅ Background indexing completed');
|
|
} catch (error) {
|
|
console.error('[Meilisearch] ❌ Background indexing failed:', error.message);
|
|
indexingState.completed = false;
|
|
// Retry after 5 minutes
|
|
setTimeout(() => {
|
|
indexingState.inProgress = false;
|
|
scheduleIndexing();
|
|
}, 5 * 60 * 1000);
|
|
}
|
|
});
|
|
};
|
|
|
|
const server = app.listen(PORT, '0.0.0.0', () => {
|
|
console.log(\`🚀 ObsiViewer server running on http://0.0.0.0:\${PORT}\`);
|
|
console.log(\`📁 Vault directory: \${vaultDir}\`);
|
|
console.log(\`📊 Performance monitoring: http://0.0.0.0:\${PORT}/__perf\`);
|
|
|
|
// Schedule background indexing (non-blocking)
|
|
scheduleIndexing();
|
|
console.log('✅ Server ready - Meilisearch indexing in background');
|
|
});
|
|
|
|
// Graceful shutdown
|
|
process.on('SIGINT', () => {
|
|
console.log('\\n🛑 Shutting down server...');
|
|
server.close(() => {
|
|
console.log('✅ Server shutdown complete');
|
|
process.exit(0);
|
|
});
|
|
});`;
|
|
|
|
content = content.replace(oldListen, newListen);
|
|
console.log('✅ app.listen() updated with deferred indexing\n');
|
|
|
|
// Step 5: Write the modified content
|
|
console.log('💾 Writing modified index.mjs...');
|
|
fs.writeFileSync(indexFile, content, 'utf-8');
|
|
console.log('✅ File written successfully\n');
|
|
|
|
// Step 6: Verify changes
|
|
console.log('🔍 Verifying changes...');
|
|
const verifyContent = fs.readFileSync(indexFile, 'utf-8');
|
|
|
|
const checks = [
|
|
{ name: 'Performance endpoint setup', pattern: 'setupPerformanceEndpoint' },
|
|
{ name: 'Deferred indexing', pattern: 'scheduleIndexing' },
|
|
{ name: 'Graceful shutdown', pattern: "process.on('SIGINT'" },
|
|
{ name: 'Performance monitoring URL', pattern: '__perf' }
|
|
];
|
|
|
|
let allPassed = true;
|
|
for (const check of checks) {
|
|
if (verifyContent.includes(check.pattern)) {
|
|
console.log(` ✅ ${check.name}`);
|
|
} else {
|
|
console.log(` ❌ ${check.name}`);
|
|
allPassed = false;
|
|
}
|
|
}
|
|
|
|
console.log('');
|
|
if (allPassed) {
|
|
console.log('✅ All verification checks passed!\n');
|
|
} else {
|
|
console.log('⚠️ Some verification checks failed\n');
|
|
}
|
|
|
|
console.log('================================');
|
|
console.log('✅ Phase 3 patch applied successfully!\n');
|
|
console.log('Next steps:');
|
|
console.log('1. Test the server: npm run start');
|
|
console.log('2. Check performance: curl http://localhost:3000/__perf');
|
|
console.log('3. Monitor cache hits in the logs');
|
|
console.log('4. Verify Meilisearch indexing in background\n');
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error applying patch:', error.message);
|
|
console.error('\nRolling back...');
|
|
if (fs.existsSync(backupFile)) {
|
|
fs.copyFileSync(backupFile, indexFile);
|
|
console.log('✅ Rollback complete');
|
|
}
|
|
process.exit(1);
|
|
}
|