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);
 | 
						|
}
 |