We use cookies to enhance your experience on the site
CodeWorlds

PROJECT: Performance optimization system for a large legion

Legion commander! Consul Caesar.js has entrusted you with the most important task in your entire Roman career - creating a complete performance optimization system for a large army of Roman forts. This will be a real test of all the skills you've acquired while studying Performance & Optimization!

Project Specification

Your army consists of 50+ Roman forts operating in different provinces, serving thousands of users simultaneously. The system must be:

1. Highly scalable

  • Horizontal scaling - automatic adding/removing of instances
  • Load balancing - intelligent traffic distribution
  • Microservices - independent services for different functions
  • Database sharding - data distribution across regions

2. Highly performant

  • Sub-200ms response times - for 95% of requests
  • 10,000+ concurrent users - per instance
  • 99.9% uptime - service availability
  • Intelligent caching - multi-level cache

3. Self-optimizing

  • Auto-scaling based on metrics
  • Predictive analytics - load prediction
  • Self-healing - automatic repairs
  • Performance monitoring - real-time insights

System Architecture

1// legion-optimization.module.ts
2import { Module } from '@nestjs/common';
3import { ConfigModule } from '@nestjs/config';
4import { RedisModule } from '@nestjs-modules/ioredis';
5import { BullModule } from '@nestjs/bull';
6import { PrometheusModule } from '@willsoto/nestjs-prometheus';
7
8@Module({
9 imports: [
10 // Environment configuration
11 ConfigModule.forRoot({
12 isGlobal: true,
13 envFilePath: ['.env.local', '.env'],
14 }),
15
16 // Redis for cache, sessions, queues
17 RedisModule.forRootAsync({
18 useFactory: (configService: ConfigService) => ({
19 type: 'single',
20 url: configService.get('REDIS_URL'),
21 options: {
22 retryDelayOnFailover: 100,
23 enableReadyCheck: false,
24 maxRetriesPerRequest: null,
25 },
26 }),
27 inject: [ConfigService],
28 }),
29
30 // Background job processing
31 BullModule.forRootAsync({
32 useFactory: (configService: ConfigService) => ({
33 redis: {
34 host: configService.get('REDIS_HOST'),
35 port: configService.get('REDIS_PORT'),
36 password: configService.get('REDIS_PASSWORD'),
37 },
38 defaultJobOptions: {
39 removeOnComplete: 100,
40 removeOnFail: 50,
41 attempts: 3,
42 backoff: {
43 type: 'exponential',
44 delay: 2000,
45 },
46 },
47 }),
48 inject: [ConfigService],
49 }),
50
51 // Metrics and monitoring
52 PrometheusModule.register({
53 path: '/metrics',
54 defaultMetrics: {
55 enabled: true,
56 config: {
57 prefix: 'legionaries_legion_',
58 },
59 },
60 }),
61
62 // Main modules
63 PerformanceModule,
64 CacheModule,
65 LoadBalancingModule,
66 AutoScalingModule,
67 MonitoringModule,
68 OptimizationModule,
69 ],
70})
71export class LegionOptimizationModule {}

Performance Monitoring Service

1// performance-monitoring.service.ts
2import { Injectable, Logger } from '@nestjs/common';
3import { Cron } from '@nestjs/schedule';
4import { InjectMetric } from '@willsoto/nestjs-prometheus';
5import { Counter, Histogram, Gauge } from 'prom-client';
6import * as os from 'os';
7import * as process from 'process';
8
9@Injectable()
10export class PerformanceMonitoringService {
11 private readonly logger = new Logger(PerformanceMonitoringService.name);
12
13 constructor(
14 @InjectMetric('http_requests_total') private requestCounter: Counter<string>,
15 @InjectMetric('http_request_duration_seconds') private requestDuration: Histogram<string>,
16 @InjectMetric('system_cpu_usage') private cpuGauge: Gauge<string>,
17 @InjectMetric('system_memory_usage') private memoryGauge: Gauge<string>,
18 @InjectMetric('active_connections') private connectionsGauge: Gauge<string>,
19 @InjectMetric('cache_hit_ratio') private cacheHitRatio: Gauge<string>,
20 ) {}
21
22 // HTTP request monitoring
23 recordHttpRequest(method: string, route: string, statusCode: number, duration: number) {
24 this.requestCounter.labels(method, route, statusCode.toString()).inc();
25 this.requestDuration.labels(method, route).observe(duration / 1000);
26 }
27
28 // System resource monitoring
29 @Cron('*/30 * * * * *') // Every 30 seconds
30 async collectSystemMetrics() {
31 try {
32 // CPU usage
33 const cpuUsage = await this.getCpuUsage();
34 this.cpuGauge.set(cpuUsage);
35
36 // Memory usage
37 const memInfo = process.memoryUsage();
38 const totalMemory = os.totalmem();
39 const usedMemory = memInfo.heapUsed + memInfo.external;
40 const memoryUsagePercent = (usedMemory / totalMemory) * 100;
41 this.memoryGauge.set(memoryUsagePercent);
42
43 // Active connections (symulowane)
44 const activeConnections = await this.getActiveConnections();
45 this.connectionsGauge.set(activeConnections);
46
47 // Cache performance
48 const cacheStats = await this.getCacheStats();
49 this.cacheHitRatio.set(cacheStats.hitRatio);
50
51 } catch (error) {
52 this.logger.error('Error collecting system metrics:', error);
53 }
54 }
55
56 // Detailed performance analysis
57 async getPerformanceReport(): Promise<PerformanceReport> {
58 const systemLoad = await this.getSystemLoad();
59 const applicationMetrics = await this.getApplicationMetrics();
60 const databaseMetrics = await this.getDatabaseMetrics();
61 const cacheMetrics = await this.getCacheMetrics();
62
63 return {
64 timestamp: new Date(),
65 system: systemLoad,
66 application: applicationMetrics,
67 database: databaseMetrics,
68 cache: cacheMetrics,
69 recommendations: this.generateRecommendations(systemLoad, applicationMetrics),
70 healthScore: this.calculateHealthScore(systemLoad, applicationMetrics, databaseMetrics),
71 };
72 }
73
74 private async getCpuUsage(): Promise<number> {
75 return new Promise((resolve) => {
76 const startUsage = process.cpuUsage();
77 const startTime = process.hrtime();
78 
79 setTimeout(() => {
80 const endUsage = process.cpuUsage(startUsage);
81 const endTime = process.hrtime(startTime);
82 
83 const userUsage = endUsage.user / 1000000; // Convert to seconds
84 const systemUsage = endUsage.system / 1000000;
85 const totalTime = endTime[0] + endTime[1] / 1000000000;
86 
87 const cpuPercent = ((userUsage + systemUsage) / totalTime) * 100;
88 resolve(Math.min(100, cpuPercent));
89 }, 100);
90 });
91 }
92
93 private async getActiveConnections(): Promise<number> {
94 // In a real application you would get this from the load balancer or reverse proxy
95 return Math.floor(Math.random() * 1000) + 100;
96 }
97
98 private async getCacheStats(): Promise<{ hitRatio: number }> {
99 // Simulation - in reality you would get this from Redis
100 const hits = Math.floor(Math.random() * 1000) + 800;
101 const misses = Math.floor(Math.random() * 200) + 50;
102 const hitRatio = hits / (hits + misses);
103 return { hitRatio };
104 }
105
106 private async getSystemLoad(): Promise<SystemLoad> {
107 const loadAvg = os.loadavg();
108 const totalMem = os.totalmem();
109 const freeMem = os.freemem();
110 const usedMem = totalMem - freeMem;
111
112 return {
113 cpu: await this.getCpuUsage(),
114 memory: {
115 total: Math.round(totalMem / 1024 / 1024), // MB
116 used: Math.round(usedMem / 1024 / 1024),
117 free: Math.round(freeMem / 1024 / 1024),
118 usagePercent: Math.round((usedMem / totalMem) * 100),
119 },
120 load: {
121 oneMinute: loadAvg[0],
122 fiveMinutes: loadAvg[1],
123 fifteenMinutes: loadAvg[2],
124 },
125 uptime: process.uptime(),
126 };
127 }
128
129 private async getApplicationMetrics(): Promise<ApplicationMetrics> {
130 // Simulated application metrics
131 return {
132 requestsPerSecond: Math.floor(Math.random() * 500) + 100,
133 averageResponseTime: Math.random() * 100 + 50,
134 p95ResponseTime: Math.random() * 200 + 100,
135 p99ResponseTime: Math.random() * 500 + 200,
136 errorRate: Math.random() * 0.05, // 0-5%
137 activeUsers: Math.floor(Math.random() * 5000) + 1000,
138 throughput: Math.floor(Math.random() * 10000) + 5000,
139 };
140 }
141
142 private async getDatabaseMetrics(): Promise<DatabaseMetrics> {
143 return {
144 connectionPoolSize: 20,
145 activeConnections: Math.floor(Math.random() * 15) + 5,
146 queryTime: {
147 avg: Math.random() * 50 + 10,
148 p95: Math.random() * 100 + 50,
149 p99: Math.random() * 200 + 100,
150 },
151 slowQueries: Math.floor(Math.random() * 5),
152 deadlocks: Math.floor(Math.random() * 2),
153 };
154 }
155
156 private async getCacheMetrics(): Promise<CacheMetrics> {
157 const hits = Math.floor(Math.random() * 10000) + 8000;
158 const misses = Math.floor(Math.random() * 2000) + 500;
159 
160 return {
161 hitRatio: hits / (hits + misses),
162 hits,
163 misses,
164 evictions: Math.floor(Math.random() * 100),
165 memoryUsage: Math.floor(Math.random() * 512) + 256, // MB
166 keyCount: Math.floor(Math.random() * 100000) + 50000,
167 };
168 }
169
170 private generateRecommendations(
171 systemLoad: SystemLoad, 
172 appMetrics: ApplicationMetrics
173 ): string[] {
174 const recommendations = [];
175
176 if (systemLoad.cpu > 80) {
177 recommendations.push('CPU usage is high - consider horizontal scaling');
178 }
179
180 if (systemLoad.memory.usagePercent > 85) {
181 recommendations.push('Memory usage is critical - optimize memory allocation');
182 }
183
184 if (appMetrics.averageResponseTime > 200) {
185 recommendations.push('Response times are slow - optimize database queries and add caching');
186 }
187
188 if (appMetrics.errorRate > 0.02) {
189 recommendations.push('Error rate is above threshold - investigate application errors');
190 }
191
192 if (systemLoad.load.oneMinute > os.cpus().length) {
193 recommendations.push('System load is high - consider load balancing');
194 }
195
196 return recommendations;
197 }
198
199 private calculateHealthScore(
200 systemLoad: SystemLoad,
201 appMetrics: ApplicationMetrics,
202 dbMetrics: DatabaseMetrics
203 ): number {
204 let score = 100;
205
206 // CPU penalty
207 if (systemLoad.cpu > 90) score -= 30;
208 else if (systemLoad.cpu > 70) score -= 15;
209 else if (systemLoad.cpu > 50) score -= 5;
210
211 // Memory penalty
212 if (systemLoad.memory.usagePercent > 90) score -= 25;
213 else if (systemLoad.memory.usagePercent > 75) score -= 10;
214
215 // Response time penalty
216 if (appMetrics.averageResponseTime > 500) score -= 20;
217 else if (appMetrics.averageResponseTime > 200) score -= 10;
218
219 // Error rate penalty
220 if (appMetrics.errorRate > 0.05) score -= 30;
221 else if (appMetrics.errorRate > 0.02) score -= 15;
222
223 // Database penalty
224 if (dbMetrics.queryTime.avg > 100) score -= 10;
225
226 return Math.max(0, score);
227 }
228}
229
230interface SystemLoad {
231 cpu: number;
232 memory: {
233 total: number;
234 used: number;
235 free: number;
236 usagePercent: number;
237 };
238 load: {
239 oneMinute: number;
240 fiveMinutes: number;
241 fifteenMinutes: number;
242 };
243 uptime: number;
244}
245
246interface ApplicationMetrics {
247 requestsPerSecond: number;
248 averageResponseTime: number;
249 p95ResponseTime: number;
250 p99ResponseTime: number;
251 errorRate: number;
252 activeUsers: number;
253 throughput: number;
254}
255
256interface DatabaseMetrics {
257 connectionPoolSize: number;
258 activeConnections: number;
259 queryTime: {
260 avg: number;
261 p95: number;
262 p99: number;
263 };
264 slowQueries: number;
265 deadlocks: number;
266}
267
268interface CacheMetrics {
269 hitRatio: number;
270 hits: number;
271 misses: number;
272 evictions: number;
273 memoryUsage: number;
274 keyCount: number;
275}
276
277interface PerformanceReport {
278 timestamp: Date;
279 system: SystemLoad;
280 application: ApplicationMetrics;
281 database: DatabaseMetrics;
282 cache: CacheMetrics;
283 recommendations: string[];
284 healthScore: number;
285}

Auto-Scaling Service

1// auto-scaling.service.ts
2import { Injectable, Logger } from '@nestjs/common';
3import { Cron } from '@nestjs/schedule';
4import { ConfigService } from '@nestjs/config';
5
6@Injectable()
7export class AutoScalingService {
8 private readonly logger = new Logger(AutoScalingService.name);
9 private scalingInProgress = false;
10 private lastScalingAction = 0;
11 private readonly minCooldown = 300000; // 5 minutes between actions
12
13 constructor(
14 private configService: ConfigService,
15 private performanceMonitoring: PerformanceMonitoringService,
16 private loadBalancer: LoadBalancerService,
17 ) {}
18
19 @Cron('*/60 * * * * *') // Every minute
20 async evaluateScaling() {
21 if (this.scalingInProgress) return;
22 
23 const now = Date.now();
24 if (now - this.lastScalingAction < this.minCooldown) return;
25
26 try {
27 const metrics = await this.performanceMonitoring.getPerformanceReport();
28 const decision = this.makeScalingDecision(metrics);
29
30 if (decision.action !== 'none') {
31 this.scalingInProgress = true;
32 await this.executeScalingAction(decision);
33 this.lastScalingAction = now;
34 }
35 } catch (error) {
36 this.logger.error('Error during scaling evaluation:', error);
37 } finally {
38 this.scalingInProgress = false;
39 }
40 }
41
42 private makeScalingDecision(metrics: PerformanceReport): ScalingDecision {
43 const thresholds = {
44 scaleOut: {
45 cpu: 70,
46 memory: 80,
47 responseTime: 300,
48 errorRate: 0.02,
49 },
50 scaleIn: {
51 cpu: 30,
52 memory: 40,
53 responseTime: 100,
54 errorRate: 0.005,
55 },
56 };
57
58 const currentInstances = this.loadBalancer.getActiveInstances().length;
59 const maxInstances = this.configService.get<number>('MAX_INSTANCES', 10);
60 const minInstances = this.configService.get<number>('MIN_INSTANCES', 2);
61
62 // Scale out conditions
63 if (currentInstances < maxInstances) {
64 if (
65 metrics.system.cpu > thresholds.scaleOut.cpu ||
66 metrics.system.memory.usagePercent > thresholds.scaleOut.memory ||
67 metrics.application.averageResponseTime > thresholds.scaleOut.responseTime ||
68 metrics.application.errorRate > thresholds.scaleOut.errorRate
69 ) {
70 const targetInstances = Math.min(
71 maxInstances,
72 currentInstances + this.calculateScaleOutAmount(metrics)
73 );
74 
75 return {
76 action: 'scale-out',
77 currentInstances,
78 targetInstances,
79 reason: this.getScaleOutReason(metrics, thresholds.scaleOut),
80 };
81 }
82 }
83
84 // Scale in conditions
85 if (currentInstances > minInstances) {
86 if (
87 metrics.system.cpu < thresholds.scaleIn.cpu &&
88 metrics.system.memory.usagePercent < thresholds.scaleIn.memory &&
89 metrics.application.averageResponseTime < thresholds.scaleIn.responseTime &&
90 metrics.application.errorRate < thresholds.scaleIn.errorRate
91 ) {
92 const targetInstances = Math.max(
93 minInstances,
94 currentInstances - 1 // Conservative scale-in
95 );
96 
97 return {
98 action: 'scale-in',
99 currentInstances,
100 targetInstances,
101 reason: 'System resources are underutilized',
102 };
103 }
104 }
105
106 return {
107 action: 'none',
108 currentInstances,
109 targetInstances: currentInstances,
110 reason: 'No scaling action required',
111 };
112 }
113
114 private calculateScaleOutAmount(metrics: PerformanceReport): number {
115 // More aggressive scaling under high load
116 if (metrics.system.cpu > 90 || metrics.application.errorRate > 0.05) {
117 return 3; // Add 3 instances
118 }
119 if (metrics.system.cpu > 80 || metrics.application.averageResponseTime > 500) {
120 return 2; // Add 2 instances
121 }
122 return 1; // Add 1 instance
123 }
124
125 private getScaleOutReason(metrics: PerformanceReport, thresholds: any): string {
126 const reasons = [];
127 
128 if (metrics.system.cpu > thresholds.cpu) {
129 reasons.push(`CPU usage: ${metrics.system.cpu.toFixed(1)}%`);
130 }
131 if (metrics.system.memory.usagePercent > thresholds.memory) {
132 reasons.push(`Memory usage: ${metrics.system.memory.usagePercent}%`);
133 }
134 if (metrics.application.averageResponseTime > thresholds.responseTime) {
135 reasons.push(`Response time: ${metrics.application.averageResponseTime.toFixed(1)}ms`);
136 }
137 if (metrics.application.errorRate > thresholds.errorRate) {
138 reasons.push(`Error rate: ${(metrics.application.errorRate * 100).toFixed(2)}%`);
139 }
140 
141 return reasons.join(', ');
142 }
143
144 private async executeScalingAction(decision: ScalingDecision): Promise<void> {
145 this.logger.log(`Executing ${decision.action}: ${decision.currentInstances} -> ${decision.targetInstances}`);
146 this.logger.log(`Reason: ${decision.reason}`);
147
148 try {
149 if (decision.action === 'scale-out') {
150 await this.scaleOut(decision.targetInstances - decision.currentInstances);
151 } else if (decision.action === 'scale-in') {
152 await this.scaleIn(decision.currentInstances - decision.targetInstances);
153 }
154 } catch (error) {
155 this.logger.error(`Failed to execute ${decision.action}:`, error);
156 throw error;
157 }
158 }
159
160 private async scaleOut(instanceCount: number): Promise<void> {
161 for (let i = 0; i < instanceCount; i++) {
162 try {
163 const instance = await this.createNewInstance();
164 await this.loadBalancer.addInstance(instance);
165 this.logger.log(`✅ Added new instance: ${instance.id}`);
166 
167 // Delay between creating instances
168 if (i < instanceCount - 1) {
169 await this.delay(5000);
170 }
171 } catch (error) {
172 this.logger.error(`Failed to create instance ${i + 1}:`, error);
173 }
174 }
175 }
176
177 private async scaleIn(instanceCount: number): Promise<void> {
178 const instances = this.loadBalancer.getActiveInstances();
179 const instancesToRemove = instances
180 .sort((a, b) => a.currentLoad - b.currentLoad) // Remove least loaded
181 .slice(0, instanceCount);
182
183 for (const instance of instancesToRemove) {
184 try {
185 await this.loadBalancer.drainInstance(instance.id);
186 await this.terminateInstance(instance.id);
187 this.logger.log(`✅ Removed instance: ${instance.id}`);
188 } catch (error) {
189 this.logger.error(`Failed to remove instance ${instance.id}:`, error);
190 }
191 }
192 }
193
194 private async createNewInstance(): Promise<ServerInstance> {
195 // Simulating creation of a new instance (in reality this would be AWS/GCP/Azure API)
196 const instanceId = `legionaries-cohort-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
197
198 return {
199 id: instanceId,
200 host: `${instanceId}.legion.local`,
201 port: 3000,
202 region: 'Hispania-central',
203 status: 'starting',
204 createdAt: new Date(),
205 currentLoad: 0,
206 maxCapacity: 1000,
207 };
208 }
209
210 private async terminateInstance(instanceId: string): Promise<void> {
211 // Simulating instance removal
212 this.logger.log(`Terminating instance: ${instanceId}`);
213 await this.delay(2000);
214 }
215
216 private delay(ms: number): Promise<void> {
217 return new Promise(resolve => setTimeout(resolve, ms));
218 }
219
220 async getScalingHistory(): Promise<ScalingEvent[]> {
221 // In a real application this would be fetched from the database
222 return [
223 {
224 timestamp: new Date(Date.now() - 3600000),
225 action: 'scale-out',
226 fromInstances: 2,
227 toInstances: 4,
228 reason: 'CPU usage: 85%, Response time: 450ms',
229 success: true,
230 },
231 {
232 timestamp: new Date(Date.now() - 7200000),
233 action: 'scale-in',
234 fromInstances: 5,
235 toInstances: 3,
236 reason: 'System resources underutilized',
237 success: true,
238 },
239 ];
240 }
241}
242
243interface ScalingDecision {
244 action: 'scale-out' | 'scale-in' | 'none';
245 currentInstances: number;
246 targetInstances: number;
247 reason: string;
248}
249
250interface ScalingEvent {
251 timestamp: Date;
252 action: string;
253 fromInstances: number;
254 toInstances: number;
255 reason: string;
256 success: boolean;
257}
258
259interface ServerInstance {
260 id: string;
261 host: string;
262 port: number;
263 region: string;
264 status: string;
265 createdAt: Date;
266 currentLoad: number;
267 maxCapacity: number;
268}

Intelligent Optimization Engine

1// optimization-engine.service.ts
2import { Injectable, Logger } from '@nestjs/common';
3import { Cron } from '@nestjs/schedule';
4
5@Injectable()
6export class OptimizationEngineService {
7 private readonly logger = new Logger(OptimizationEngineService.name);
8 private learningData: PerformanceDataPoint[] = [];
9 private optimizationHistory: OptimizationAction[] = [];
10
11 constructor(
12 private performanceMonitoring: PerformanceMonitoringService,
13 private cacheManager: IntelligentCacheService,
14 private databaseOptimizer: DatabaseOptimizerService,
15 private autoScaling: AutoScalingService,
16 ) {}
17
18 @Cron('*/300 * * * * *') // Every 5 minutes
19 async runOptimizationCycle() {
20 try {
21 this.logger.log('Starting optimization cycle');
22 
23 // Collect performance data
24 const currentMetrics = await this.performanceMonitoring.getPerformanceReport();
25 this.addDataPoint(currentMetrics);
26
27 // Analyze trends
28 const trends = this.analyzeTrends();
29 
30 // Predict future load
31 const predictions = this.predictFutureLoad();
32 
33 // Generate optimization recommendations
34 const recommendations = await this.generateOptimizationRecommendations(
35 currentMetrics,
36 trends,
37 predictions
38 );
39
40 // Execute automatic optimizations
41 await this.executeAutomaticOptimizations(recommendations);
42
43 this.logger.log(`✅ Optimization cycle completed. Applied ${recommendations.filter(r => r.autoApply).length} optimizations`);
44 
45 } catch (error) {
46 this.logger.error('Error during optimization cycle:', error);
47 }
48 }
49
50 private addDataPoint(metrics: PerformanceReport) {
51 this.learningData.push({
52 timestamp: new Date(),
53 metrics,
54 context: this.getCurrentContext(),
55 });
56
57 // Keep only the last 1000 data points
58 if (this.learningData.length > 1000) {
59 this.learningData = this.learningData.slice(-1000);
60 }
61 }
62
63 private analyzeTrends(): TrendAnalysis {
64 if (this.learningData.length < 10) {
65 return {
66 cpuTrend: 'stable',
67 memoryTrend: 'stable',
68 responseTimeTrend: 'stable',
69 errorRateTrend: 'stable',
70 confidenceLevel: 0.1,
71 };
72 }
73
74 const recent = this.learningData.slice(-60); // Last hour (every 5 min)
75 const older = this.learningData.slice(-120, -60); // Previous hour
76
77 return {
78 cpuTrend: this.calculateTrend(
79 older.map(d => d.metrics.system.cpu),
80 recent.map(d => d.metrics.system.cpu)
81 ),
82 memoryTrend: this.calculateTrend(
83 older.map(d => d.metrics.system.memory.usagePercent),
84 recent.map(d => d.metrics.system.memory.usagePercent)
85 ),
86 responseTimeTrend: this.calculateTrend(
87 older.map(d => d.metrics.application.averageResponseTime),
88 recent.map(d => d.metrics.application.averageResponseTime)
89 ),
90 errorRateTrend: this.calculateTrend(
91 older.map(d => d.metrics.application.errorRate),
92 recent.map(d => d.metrics.application.errorRate)
93 ),
94 confidenceLevel: Math.min(recent.length / 60, 1),
95 };
96 }
97
98 private calculateTrend(oldValues: number[], newValues: number[]): 'increasing' | 'decreasing' | 'stable' {
99 if (oldValues.length === 0 || newValues.length === 0) return 'stable';
100
101 const oldAvg = oldValues.reduce((a, b) => a + b, 0) / oldValues.length;
102 const newAvg = newValues.reduce((a, b) => a + b, 0) / newValues.length;
103 
104 const changePercent = ((newAvg - oldAvg) / oldAvg) * 100;
105
106 if (changePercent > 10) return 'increasing';
107 if (changePercent < -10) return 'decreasing';
108 return 'stable';
109 }
110
111 private predictFutureLoad(): LoadPrediction {
112 // Simplified ML-like prediction based on historical patterns
113 const hourOfDay = new Date().getHours();
114 const dayOfWeek = new Date().getDay();
115 
116 // Simulating load patterns
117 const hourlyPattern = this.getHourlyLoadPattern();
118 const weeklyPattern = this.getWeeklyLoadPattern();
119 
120 const predictedCpuIncrease = hourlyPattern[hourOfDay] * weeklyPattern[dayOfWeek];
121 const predictedMemoryIncrease = predictedCpuIncrease * 0.8; // Memory usually follows CPU
122 
123 return {
124 nextHourLoad: {
125 cpu: Math.min(100, predictedCpuIncrease),
126 memory: Math.min(100, predictedMemoryIncrease),
127 requests: Math.floor(predictedCpuIncrease * 10),
128 },
129 confidence: 0.75,
130 factors: ['hourly_pattern', 'weekly_pattern', 'historical_data'],
131 };
132 }
133
134 private getHourlyLoadPattern(): number[] {
135 // Example load pattern throughout the day
136 return [
137 20, 15, 10, 8, 6, 8, // 00-05: Noc
138 15, 25, 40, 60, 80, 90, // 06-11: Morning/before noon
139 95, 85, 75, 80, 85, 90, // 12-17: Noon/afternoon
140 70, 60, 50, 40, 30, 25 // 18-23: Evening
141 ];
142 }
143
144 private getWeeklyLoadPattern(): number[] {
145 // Weekly pattern (0 = Sunday)
146 return [0.7, 1.0, 1.0, 1.0, 1.0, 1.0, 0.8]; // Less on weekends
147 }
148
149 private async generateOptimizationRecommendations(
150 metrics: PerformanceReport,
151 trends: TrendAnalysis,
152 predictions: LoadPrediction
153 ): Promise<OptimizationRecommendation[]> {
154 const recommendations: OptimizationRecommendation[] = [];
155
156 // Cache optimization
157 if (metrics.cache.hitRatio < 0.8) {
158 recommendations.push({
159 type: 'cache',
160 priority: 'high',
161 action: 'optimize_cache_strategy',
162 description: `Cache hit ratio is ${(metrics.cache.hitRatio * 100).toFixed(1)}% - optimize caching strategy`,
163 autoApply: true,
164 estimatedImpact: 'Improve response time by 20-30%',
165 implementation: async () => {
166 await this.cacheManager.optimizeCacheStrategy();
167 },
168 });
169 }
170
171 // Database optimization
172 if (metrics.database.queryTime.avg > 100) {
173 recommendations.push({
174 type: 'database',
175 priority: 'high',
176 action: 'optimize_slow_queries',
177 description: `Average query time is ${metrics.database.queryTime.avg.toFixed(1)}ms - optimize database queries`,
178 autoApply: false, // Requires manual review
179 estimatedImpact: 'Reduce query time by 40-60%',
180 implementation: async () => {
181 await this.databaseOptimizer.optimizeSlowQueries();
182 },
183 });
184 }
185
186 // Predictive scaling
187 if (predictions.nextHourLoad.cpu > 80 && trends.cpuTrend === 'increasing') {
188 recommendations.push({
189 type: 'scaling',
190 priority: 'medium',
191 action: 'predictive_scale_out',
192 description: 'Predicted high load in next hour - scale out preemptively',
193 autoApply: true,
194 estimatedImpact: 'Prevent performance degradation',
195 implementation: async () => {
196 // Auto-scaling already exists, but we can be more proactive
197 this.logger.log('Triggering predictive scaling based on load prediction');
198 },
199 });
200 }
201
202 // Memory optimization
203 if (metrics.system.memory.usagePercent > 85) {
204 recommendations.push({
205 type: 'memory',
206 priority: 'high',
207 action: 'optimize_memory_usage',
208 description: `Memory usage is ${metrics.system.memory.usagePercent}% - optimize memory allocation`,
209 autoApply: true,
210 estimatedImpact: 'Reduce memory usage by 15-25%',
211 implementation: async () => {
212 await this.optimizeMemoryUsage();
213 },
214 });
215 }
216
217 return recommendations;
218 }
219
220 private async executeAutomaticOptimizations(
221 recommendations: OptimizationRecommendation[]
222 ): Promise<void> {
223 const autoRecommendations = recommendations.filter(r => r.autoApply);
224 
225 for (const recommendation of autoRecommendations) {
226 try {
227 this.logger.log(` Applying optimization: ${recommendation.action}`);
228 await recommendation.implementation();
229 
230 this.optimizationHistory.push({
231 timestamp: new Date(),
232 type: recommendation.type,
233 action: recommendation.action,
234 success: true,
235 impact: recommendation.estimatedImpact,
236 });
237 
238 } catch (error) {
239 this.logger.error(`Failed to apply optimization ${recommendation.action}:`, error);
240 
241 this.optimizationHistory.push({
242 timestamp: new Date(),
243 type: recommendation.type,
244 action: recommendation.action,
245 success: false,
246 error: error.message,
247 });
248 }
249 }
250 }
251
252 private async optimizeMemoryUsage(): Promise<void> {
253 // Clear caches
254 await this.cacheManager.clearOldEntries();
255 
256 // Run garbage collection
257 if (global.gc) {
258 global.gc();
259 }
260 
261 // Optimize memory allocation
262 await this.optimizeMemoryAllocation();
263 }
264
265 private async optimizeMemoryAllocation(): Promise<void> {
266 // Simulating memory allocation optimization
267 this.logger.log('🧠 Optimizing memory allocation patterns');
268 }
269
270 private getCurrentContext(): PerformanceContext {
271 const now = new Date();
272 return {
273 hour: now.getHours(),
274 dayOfWeek: now.getDay(),
275 isWeekend: now.getDay() === 0 || now.getDay() === 6,
276 isBusinessHours: now.getHours() >= 9 && now.getHours() <= 17,
277 activeInstances: this.autoScaling.getActiveInstances?.()?.length || 0,
278 };
279 }
280
281 async getOptimizationReport(): Promise<OptimizationReport> {
282 const recentOptimizations = this.optimizationHistory.slice(-20);
283 const successRate = recentOptimizations.length > 0
284 ? recentOptimizations.filter(o => o.success).length / recentOptimizations.length
285 : 0;
286
287 return {
288 timestamp: new Date(),
289 totalOptimizations: this.optimizationHistory.length,
290 recentOptimizations,
291 successRate,
292 learningDataPoints: this.learningData.length,
293 trends: this.analyzeTrends(),
294 predictions: this.predictFutureLoad(),
295 };
296 }
297}
298
299interface PerformanceDataPoint {
300 timestamp: Date;
301 metrics: PerformanceReport;
302 context: PerformanceContext;
303}
304
305interface PerformanceContext {
306 hour: number;
307 dayOfWeek: number;
308 isWeekend: boolean;
309 isBusinessHours: boolean;
310 activeInstances: number;
311}
312
313interface TrendAnalysis {
314 cpuTrend: 'increasing' | 'decreasing' | 'stable';
315 memoryTrend: 'increasing' | 'decreasing' | 'stable';
316 responseTimeTrend: 'increasing' | 'decreasing' | 'stable';
317 errorRateTrend: 'increasing' | 'decreasing' | 'stable';
318 confidenceLevel: number;
319}
320
321interface LoadPrediction {
322 nextHourLoad: {
323 cpu: number;
324 memory: number;
325 requests: number;
326 };
327 confidence: number;
328 factors: string[];
329}
330
331interface OptimizationRecommendation {
332 type: 'cache' | 'database' | 'scaling' | 'memory' | 'network';
333 priority: 'low' | 'medium' | 'high' | 'critical';
334 action: string;
335 description: string;
336 autoApply: boolean;
337 estimatedImpact: string;
338 implementation: () => Promise<void>;
339}
340
341interface OptimizationAction {
342 timestamp: Date;
343 type: string;
344 action: string;
345 success: boolean;
346 impact?: string;
347 error?: string;
348}
349
350interface OptimizationReport {
351 timestamp: Date;
352 totalOptimizations: number;
353 recentOptimizations: OptimizationAction[];
354 successRate: number;
355 learningDataPoints: number;
356 trends: TrendAnalysis;
357 predictions: LoadPrediction;
358}

Legion Management Dashboard

1// legion-dashboard.controller.ts
2import { Controller, Get, Post, Body, Query, UseGuards } from '@nestjs/common';
3import { ApiTags, ApiOperation } from '@nestjs/swagger';
4
5@ApiTags('Legion Management')
6@Controller('admin/legion')
7@UseGuards(AdminGuard)
8export class LegionDashboardController {
9 constructor(
10 private performanceMonitoring: PerformanceMonitoringService,
11 private autoScaling: AutoScalingService,
12 private optimizationEngine: OptimizationEngineService,
13 private loadBalancer: LoadBalancerService,
14 private cacheManager: IntelligentCacheService,
15 ) {}
16
17 @Get('dashboard')
18 @ApiOperation({ summary: 'Get complete legion dashboard' })
19 async getLegionDashboard() {
20 const [
21 performanceReport,
22 scalingHistory,
23 optimizationReport,
24 loadBalancerStatus,
25 cacheStats
26 ] = await Promise.all([
27 this.performanceMonitoring.getPerformanceReport(),
28 this.autoScaling.getScalingHistory(),
29 this.optimizationEngine.getOptimizationReport(),
30 this.loadBalancer.getStatus(),
31 this.cacheManager.getStats()
32 ]);
33
34 return {
35 timestamp: new Date(),
36 legionOverview: {
37 activeLegions: loadBalancerStatus.activeInstances,
38 totalCapacity: loadBalancerStatus.totalCapacity,
39 currentLoad: loadBalancerStatus.currentLoad,
40 healthScore: performanceReport.healthScore,
41 status: this.calculateLegionStatus(performanceReport.healthScore),
42 },
43 performance: performanceReport,
44 autoScaling: {
45 history: scalingHistory,
46 nextEvaluation: new Date(Date.now() + 60000), // Next minute
47 },
48 optimization: optimizationReport,
49 loadBalancing: loadBalancerStatus,
50 cache: cacheStats,
51 alerts: this.generateAlerts(performanceReport),
52 };
53 }
54
55 @Get('recommendations')
56 @ApiOperation({ summary: 'Get optimization recommendations' })
57 async getRecommendations() {
58 const performanceReport = await this.performanceMonitoring.getPerformanceReport();
59 const trends = this.optimizationEngine.analyzeTrends();
60 const predictions = this.optimizationEngine.predictFutureLoad();
61 
62 return this.optimizationEngine.generateOptimizationRecommendations(
63 performanceReport,
64 trends,
65 predictions
66 );
67 }
68
69 @Post('optimize')
70 @ApiOperation({ summary: 'Trigger manual optimization' })
71 async triggerOptimization(@Body() options: { type?: string; force?: boolean }) {
72 await this.optimizationEngine.runOptimizationCycle();
73 return { message: 'Optimization cycle triggered successfully' };
74 }
75
76 @Get('metrics/export')
77 @ApiOperation({ summary: 'Export performance metrics' })
78 async exportMetrics(@Query('format') format: string = 'json', @Query('hours') hours: string = '24') {
79 const hoursNum = parseInt(hours);
80 const metrics = await this.performanceMonitoring.getHistoricalMetrics(hoursNum);
81 
82 if (format === 'csv') {
83 return this.convertToCSV(metrics);
84 }
85 
86 return metrics;
87 }
88
89 @Post('scaling/manual')
90 @ApiOperation({ summary: 'Manual scaling action' })
91 async manualScaling(@Body() action: { type: 'scale-out' | 'scale-in'; instances: number }) {
92 if (action.type === 'scale-out') {
93 await this.autoScaling.scaleOut(action.instances);
94 } else {
95 await this.autoScaling.scaleIn(action.instances);
96 }
97 
98 return { message: `Manual ${action.type} of ${action.instances} instances initiated` };
99 }
100
101 @Get('health-check')
102 @ApiOperation({ summary: 'Comprehensive legion health check' })
103 async healthCheck() {
104 const checks = await Promise.allSettled([
105 this.checkDatabaseHealth(),
106 this.checkRedisHealth(),
107 this.checkLoadBalancerHealth(),
108 this.checkInstancesHealth(),
109 ]);
110
111 const results = checks.map((check, index) => ({
112 service: ['database', 'redis', 'load-balancer', 'instances'][index],
113 status: check.status === 'fulfilled' ? 'healthy' : 'unhealthy',
114 details: check.status === 'fulfilled' ? check.value : check.reason.message,
115 }));
116
117 const overallHealth = results.every(r => r.status === 'healthy') ? 'healthy' : 'degraded';
118
119 return {
120 timestamp: new Date(),
121 overallHealth,
122 services: results,
123 };
124 }
125
126 private calculateLegionStatus(healthScore: number): 'optimal' | 'good' | 'warning' | 'critical' {
127 if (healthScore >= 90) return 'optimal';
128 if (healthScore >= 75) return 'good';
129 if (healthScore >= 50) return 'warning';
130 return 'critical';
131 }
132
133 private generateAlerts(performanceReport: PerformanceReport): Alert[] {
134 const alerts: Alert[] = [];
135
136 if (performanceReport.system.cpu > 90) {
137 alerts.push({
138 level: 'critical',
139 message: `Critical CPU usage: ${performanceReport.system.cpu.toFixed(1)}%`,
140 category: 'performance',
141 timestamp: new Date(),
142 });
143 }
144
145 if (performanceReport.application.errorRate > 0.05) {
146 alerts.push({
147 level: 'critical',
148 message: `High error rate: ${(performanceReport.application.errorRate * 100).toFixed(2)}%`,
149 category: 'reliability',
150 timestamp: new Date(),
151 });
152 }
153
154 if (performanceReport.application.averageResponseTime > 500) {
155 alerts.push({
156 level: 'warning',
157 message: `Slow response times: ${performanceReport.application.averageResponseTime.toFixed(1)}ms`,
158 category: 'performance',
159 timestamp: new Date(),
160 });
161 }
162
163 return alerts;
164 }
165
166 private async checkDatabaseHealth(): Promise<string> {
167 // Simulate database health check
168 return 'Database connections: 15/20, Query time: 45ms avg';
169 }
170
171 private async checkRedisHealth(): Promise<string> {
172 // Simulate Redis health check
173 return 'Redis connected, Memory: 256MB, Hit ratio: 94%';
174 }
175
176 private async checkLoadBalancerHealth(): Promise<string> {
177 const status = await this.loadBalancer.getStatus();
178 return `Active instances: ${status.activeInstances}, Load: ${status.currentLoad}%`;
179 }
180
181 private async checkInstancesHealth(): Promise<string> {
182 const instances = this.loadBalancer.getActiveInstances();
183 const healthyInstances = instances.filter(i => i.status === 'healthy').length;
184 return `Healthy instances: ${healthyInstances}/${instances.length}`;
185 }
186
187 private convertToCSV(data: any[]): string {
188 // Simplified CSV conversion
189 if (data.length === 0) return '';
190 
191 const headers = Object.keys(data[0]).join(',');
192 const rows = data.map(row => Object.values(row).join(','));
193 
194 return [headers, ...rows].join('
195');
196 }
197}
198
199interface Alert {
200 level: 'info' | 'warning' | 'critical';
201 message: string;
202 category: 'performance' | 'reliability' | 'security' | 'capacity';
203 timestamp: Date;
204}

Tasks to complete

Part 1: Basic implementation (4-6 hours)

  1. Implement Performance Monitoring Service
  • System metrics (CPU, memory, disk)
  • Application metrics (response time, throughput, errors)
  • Database and cache metrics
  • Prometheus integration
  1. Create Auto-Scaling Service
  • Scaling decision logic
  • Thresholds and cooldown periods
  • Load balancer integration
  • Scaling action history and audit
  1. Add Intelligent Cache Management
  • Multi-level cache with Redis
  • Automatic eviction and warming
  • Cache analytics and optimization

Part 2: Advanced optimization (6-8 hours)

  1. Implement Optimization Engine
  • Machine learning for load prediction
  • Automatic recommendation generation
  • Trend analysis and pattern recognition
  • Self-healing capabilities
  1. Create Advanced Load Balancer
  • Multi-criteria balancing algorithms
  • Health checking and circuit breakers
  • Geographic routing
  • Sticky sessions and session affinity
  1. Add Database Performance Optimization
  • Query optimization and slow query detection
  • Connection pooling optimization
  • Index recommendations
  • Query plan analysis

Part 3: Monitoring and Alerting (3-4 hours)

  1. Build Legion Management Dashboard
  • Real-time metrics and visualizations
  • Alert management system
  • Performance trending
  • Capacity planning tools
  1. Add Advanced Alerting
  • Smart alerting with ML-based anomaly detection
  • Alert correlation and noise reduction
  • Multi-channel notifications (Slack, email, SMS)
  • Escalation policies

Part 4: Testing and Deployment (3-4 hours)

  1. Performance Testing Suite
  • Load testing scenarios
  • Stress testing limits
  • Chaos engineering tests
  • Automated performance regression tests
  1. CI/CD Pipeline with Performance Gates
  • Automated performance benchmarks
  • Performance budget enforcement
  • Canary deployments with rollback
  • Blue-green deployment strategy

Evaluation criteria

Your project will be evaluated for:

Scalability - whether the system handles growing load ✓ Performance - response times, throughput, resource efficiency ✓ Reliability - uptime, error handling, graceful degradation ✓ Observability - monitoring, logging, metrics, tracing ✓ Automation - self-healing, auto-scaling, optimization ✓ Code quality - architecture, testing, documentation

Bonus Features (for ambitious legates)

  • Geographic Distribution - multi-region deployment with data replication
  • Cost Optimization - spot instances, reserved capacity planning
  • Security Monitoring - performance impact of security measures
  • ML-Based Predictions - advanced load forecasting
  • Chaos Engineering - automated resilience testing

Good luck, legion commander! Your mission is to create the most efficient and intelligent army of Roman forts that has ever guarded the digital provinces!

Go to CodeWorlds