UNPKG

mcp-quiz-server

Version:

🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.

189 lines (188 loc) 7.95 kB
"use strict"; /** * @fileoverview Performance Decorator - Automatic Performance Tracking * @version 1.0.0 * @since 2025-07-30 * @lastUpdated 2025-07-30 * @module PerformanceDecorator * @description Decorators for automatic performance monitoring of Clean Architecture handlers * @contributors Claude Code Agent * @dependencies PerformanceMonitor * @requirements REQ-PERF-002 (Automatic Performance Tracking) */ Object.defineProperty(exports, "__esModule", { value: true }); exports.TrackPerformance = TrackPerformance; exports.TrackDatabaseOperation = TrackDatabaseOperation; exports.TrackCacheOperation = TrackCacheOperation; exports.TrackEventOperation = TrackEventOperation; exports.TrackClass = TrackClass; exports.withPerformanceTracking = withPerformanceTracking; const PerformanceMonitor_1 = require("../../infrastructure/monitoring/PerformanceMonitor"); /** * Decorator for automatic performance tracking of command handlers */ function TrackPerformance(operationType) { return function (target, propertyName, descriptor) { const method = descriptor.value; const finalOperationType = operationType || `${target.constructor.name}.${propertyName}`; descriptor.value = async function (...args) { const tracker = PerformanceMonitor_1.performanceMonitor.startOperation(finalOperationType); try { console.log(`⚡ Starting ${finalOperationType}`); const result = await method.apply(this, args); const metrics = tracker.complete(true); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); console.log(`✅ Completed ${finalOperationType} in ${metrics.duration}ms`); return result; } catch (error) { const metrics = tracker.complete(false); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); console.error(`❌ Failed ${finalOperationType} in ${metrics.duration}ms:`, error.message || error); throw error; } }; return descriptor; }; } /** * Decorator for tracking database operations */ function TrackDatabaseOperation(operationType) { return function (target, propertyName, descriptor) { const method = descriptor.value; const finalOperationType = operationType || `DB.${target.constructor.name}.${propertyName}`; descriptor.value = async function (...args) { const tracker = PerformanceMonitor_1.performanceMonitor.startOperation(finalOperationType); tracker.recordDatabaseQuery(); try { const result = await method.apply(this, args); const metrics = tracker.complete(true); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); return result; } catch (error) { const metrics = tracker.complete(false); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); throw error; } }; return descriptor; }; } /** * Decorator for tracking cache operations */ function TrackCacheOperation(operationType) { return function (target, propertyName, descriptor) { const method = descriptor.value; const finalOperationType = operationType || `Cache.${target.constructor.name}.${propertyName}`; descriptor.value = async function (...args) { const tracker = PerformanceMonitor_1.performanceMonitor.startOperation(finalOperationType); try { const result = await method.apply(this, args); // Determine if it was a cache hit based on method name or result const isCacheHit = propertyName.includes('get') && result !== null && result !== undefined; tracker.recordCacheHit(isCacheHit); const metrics = tracker.complete(true); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); return result; } catch (error) { tracker.recordCacheHit(false); const metrics = tracker.complete(false); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); throw error; } }; return descriptor; }; } /** * Decorator for tracking event publishing */ function TrackEventOperation(operationType) { return function (target, propertyName, descriptor) { const method = descriptor.value; const finalOperationType = operationType || `Event.${target.constructor.name}.${propertyName}`; descriptor.value = async function (...args) { const tracker = PerformanceMonitor_1.performanceMonitor.startOperation(finalOperationType); tracker.recordEvent(); try { const result = await method.apply(this, args); const metrics = tracker.complete(true); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); return result; } catch (error) { const metrics = tracker.complete(false); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); throw error; } }; return descriptor; }; } /** * Class decorator for automatic performance tracking of all methods */ function TrackClass(operationPrefix) { return function (constructor) { const prefix = operationPrefix || constructor.name; // Get all method names const methodNames = Object.getOwnPropertyNames(constructor.prototype).filter(name => name !== 'constructor' && typeof constructor.prototype[name] === 'function'); // Wrap each method with performance tracking methodNames.forEach(methodName => { const originalMethod = constructor.prototype[methodName]; const operationType = `${prefix}.${methodName}`; constructor.prototype[methodName] = async function (...args) { const tracker = PerformanceMonitor_1.performanceMonitor.startOperation(operationType); try { const result = await originalMethod.apply(this, args); const metrics = tracker.complete(true); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); return result; } catch (error) { const metrics = tracker.complete(false); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); throw error; } }; }); return constructor; }; } /** * Helper function for manual performance tracking with context */ async function withPerformanceTracking(operationType, operation, context) { const tracker = PerformanceMonitor_1.performanceMonitor.startOperation(operationType); // Apply context if provided if (context) { if (context.databaseQueries) { for (let i = 0; i < context.databaseQueries; i++) { tracker.recordDatabaseQuery(); } } if (context.eventCount) { for (let i = 0; i < context.eventCount; i++) { tracker.recordEvent(); } } if (context.cacheHit !== undefined) { tracker.recordCacheHit(context.cacheHit); } } try { const result = await operation(tracker); const metrics = tracker.complete(true); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); return result; } catch (error) { const metrics = tracker.complete(false); PerformanceMonitor_1.performanceMonitor.recordMetrics(metrics); throw error; } }