Skip to main content
Glama
Coder-RL
by Coder-RL
analytics-engine.ts32.1 kB
import { EventEmitter } from 'events'; export interface AnalyticsQuery { id: string; name: string; description?: string; type: 'sql' | 'nosql' | 'graph' | 'timeseries' | 'ml' | 'streaming'; query: string; parameters: Record<string, any>; datasources: string[]; cache: CacheConfig; optimization: OptimizationConfig; security: SecurityConfig; scheduling?: ScheduleConfig; metadata: QueryMetadata; } export interface CacheConfig { enabled: boolean; ttl: number; strategy: 'memory' | 'disk' | 'distributed'; invalidation: 'time' | 'dependency' | 'manual'; compression: boolean; } export interface OptimizationConfig { enabled: boolean; pushdown: boolean; vectorization: boolean; parallelization: boolean; indexHints: string[]; costBased: boolean; } export interface SecurityConfig { rowLevelSecurity: boolean; columnMasking: boolean; auditLogging: boolean; dataClassification: string[]; } export interface ScheduleConfig { enabled: boolean; cron: string; timezone: string; retries: number; notifications: string[]; } export interface QueryMetadata { tags: string[]; owner: string; version: string; createdAt: Date; updatedAt: Date; executionHistory: QueryExecution[]; } export interface QueryExecution { id: string; queryId: string; status: 'running' | 'completed' | 'failed' | 'cancelled'; startTime: Date; endTime?: Date; duration?: number; parameters: Record<string, any>; results: QueryResult; metrics: ExecutionMetrics; errors: QueryError[]; cached: boolean; userId: string; } export interface QueryResult { columns: ColumnInfo[]; rows: any[][]; rowCount: number; approximateRowCount?: number; hasMore: boolean; resultId?: string; metadata: ResultMetadata; } export interface ColumnInfo { name: string; type: string; nullable: boolean; description?: string; semanticType?: 'dimension' | 'measure' | 'timestamp' | 'id'; } export interface ResultMetadata { queryPlan?: string; partitionsScanned?: number; bytesScanned: number; cacheHit: boolean; dataFreshness?: Date; warnings: string[]; } export interface ExecutionMetrics { planningTime: number; executionTime: number; queueTime: number; cpuTime: number; memoryPeak: number; diskSpilled: number; networkIO: number; cacheHits: number; cacheMisses: number; } export interface QueryError { code: string; message: string; severity: 'error' | 'warning' | 'info'; line?: number; column?: number; suggestion?: string; } export interface DataSource { id: string; name: string; type: 'postgresql' | 'mysql' | 'mongodb' | 'elasticsearch' | 'redis' | 's3' | 'bigquery' | 'snowflake'; connection: ConnectionConfig; schema: DataSourceSchema; capabilities: DataSourceCapabilities; status: 'online' | 'offline' | 'degraded'; lastUpdated: Date; } export interface ConnectionConfig { host?: string; port?: number; database?: string; username?: string; password?: string; ssl?: boolean; pool?: PoolConfig; timeout?: number; retries?: number; connectionString?: string; parameters?: Record<string, any>; } export interface PoolConfig { min: number; max: number; idle: number; acquire: number; evict: number; } export interface DataSourceSchema { tables: TableInfo[]; views: ViewInfo[]; functions: FunctionInfo[]; lastRefreshed: Date; } export interface TableInfo { name: string; schema: string; columns: ColumnInfo[]; primaryKey: string[]; foreignKeys: ForeignKeyInfo[]; indexes: IndexInfo[]; statistics: TableStatistics; partitioning?: PartitionInfo; } export interface ViewInfo { name: string; schema: string; definition: string; columns: ColumnInfo[]; dependencies: string[]; } export interface FunctionInfo { name: string; schema: string; returnType: string; parameters: ParameterInfo[]; description?: string; } export interface ForeignKeyInfo { columns: string[]; referencedTable: string; referencedColumns: string[]; } export interface IndexInfo { name: string; columns: string[]; unique: boolean; type: string; statistics?: IndexStatistics; } export interface ParameterInfo { name: string; type: string; required: boolean; default?: any; } export interface TableStatistics { rowCount: number; size: number; lastAnalyzed: Date; columnStats: Record<string, ColumnStatistics>; } export interface ColumnStatistics { distinctCount: number; nullCount: number; min: any; max: any; avgLength?: number; histogram?: HistogramBucket[]; } export interface HistogramBucket { lower: any; upper: any; count: number; frequency: number; } export interface IndexStatistics { uniqueness: number; selectivity: number; lastUsed: Date; usage: number; } export interface PartitionInfo { type: 'hash' | 'range' | 'list'; columns: string[]; partitions: PartitionDetail[]; } export interface PartitionDetail { name: string; expression: string; statistics: TableStatistics; } export interface DataSourceCapabilities { supportsTransactions: boolean; supportsJoins: boolean; supportsAggregation: boolean; supportsWindowFunctions: boolean; supportsCTE: boolean; supportsFullTextSearch: boolean; maxQueryComplexity: number; maxConcurrentQueries: number; supportedFunctions: string[]; } export interface AnalyticsWorkspace { id: string; name: string; description?: string; owner: string; members: WorkspaceMember[]; queries: string[]; dashboards: string[]; datasets: string[]; permissions: WorkspacePermissions; settings: WorkspaceSettings; createdAt: Date; updatedAt: Date; } export interface WorkspaceMember { userId: string; role: 'owner' | 'editor' | 'viewer'; permissions: string[]; addedAt: Date; } export interface WorkspacePermissions { canExecuteQueries: boolean; canCreateQueries: boolean; canModifyQueries: boolean; canDeleteQueries: boolean; canCreateDashboards: boolean; canModifyDashboards: boolean; canManageMembers: boolean; canExportData: boolean; } export interface WorkspaceSettings { defaultDataSource: string; queryTimeout: number; resultLimit: number; autoSave: boolean; cachingEnabled: boolean; auditLogging: boolean; } export interface Dashboard { id: string; name: string; description?: string; workspaceId: string; owner: string; layout: DashboardLayout; widgets: DashboardWidget[]; filters: DashboardFilter[]; variables: DashboardVariable[]; settings: DashboardSettings; sharing: SharingSettings; createdAt: Date; updatedAt: Date; } export interface DashboardLayout { type: 'grid' | 'flex'; columns: number; rowHeight: number; margin: number; padding: number; } export interface DashboardWidget { id: string; type: 'chart' | 'table' | 'metric' | 'text' | 'filter' | 'image'; title: string; position: WidgetPosition; size: WidgetSize; queryId?: string; configuration: WidgetConfiguration; styling: WidgetStyling; } export interface WidgetPosition { x: number; y: number; } export interface WidgetSize { width: number; height: number; } export interface WidgetConfiguration { chartType?: 'line' | 'bar' | 'pie' | 'scatter' | 'area' | 'heatmap'; xAxis?: string; yAxis?: string[]; groupBy?: string[]; aggregation?: string; filters?: Record<string, any>; sorting?: SortConfig[]; pagination?: PaginationConfig; formatting?: FormattingConfig; } export interface SortConfig { column: string; direction: 'asc' | 'desc'; } export interface PaginationConfig { enabled: boolean; pageSize: number; showTotal: boolean; } export interface FormattingConfig { numberFormat?: string; dateFormat?: string; colorScheme?: string; conditionalFormatting?: ConditionalFormat[]; } export interface ConditionalFormat { condition: string; format: FormatStyle; } export interface FormatStyle { backgroundColor?: string; textColor?: string; fontWeight?: string; fontSize?: string; } export interface WidgetStyling { backgroundColor?: string; borderColor?: string; borderWidth?: number; borderRadius?: number; shadow?: boolean; padding?: number; margin?: number; } export interface DashboardFilter { id: string; name: string; type: 'select' | 'multiselect' | 'range' | 'date' | 'text'; column: string; values?: any[]; defaultValue?: any; required: boolean; cascading: boolean; } export interface DashboardVariable { name: string; type: 'static' | 'query' | 'url' | 'user'; value: any; query?: string; options?: any[]; } export interface DashboardSettings { refreshInterval: number; timezone: string; theme: 'light' | 'dark' | 'auto'; responsive: boolean; fullscreen: boolean; exportFormats: string[]; } export interface SharingSettings { public: boolean; allowedUsers: string[]; allowedGroups: string[]; embedEnabled: boolean; embedDomains: string[]; expirationDate?: Date; } export interface AnalyticsEngineConfig { defaultTimeout: number; maxConcurrentQueries: number; resultCacheSize: number; optimizationLevel: 'none' | 'basic' | 'aggressive'; security: { rowLevelSecurity: boolean; columnMasking: boolean; auditLogging: boolean; }; performance: { queryPlanning: boolean; vectorization: boolean; parallelization: boolean; caching: boolean; }; } export class AnalyticsEngine extends EventEmitter { private dataSources = new Map<string, DataSource>(); private queries = new Map<string, AnalyticsQuery>(); private executions = new Map<string, QueryExecution>(); private workspaces = new Map<string, AnalyticsWorkspace>(); private dashboards = new Map<string, Dashboard>(); private resultCache = new Map<string, CachedResult>(); private queryOptimizer: QueryOptimizer; private securityManager: SecurityManager; constructor(private config: AnalyticsEngineConfig) { super(); this.queryOptimizer = new QueryOptimizer(config); this.securityManager = new SecurityManager(config.security); this.startCacheEviction(); this.startPerformanceMonitoring(); } // Data Source Management async registerDataSource(dataSource: DataSource): Promise<void> { try { // Test connection await this.testConnection(dataSource); // Refresh schema await this.refreshSchema(dataSource); this.dataSources.set(dataSource.id, dataSource); this.emit('dataSourceRegistered', { dataSource }); } catch (error) { this.emit('error', { operation: 'registerDataSource', error }); throw error; } } async updateDataSource(dataSourceId: string, updates: Partial<DataSource>): Promise<boolean> { try { const dataSource = this.dataSources.get(dataSourceId); if (!dataSource) { throw new Error(`Data source ${dataSourceId} not found`); } Object.assign(dataSource, updates, { lastUpdated: new Date() }); // Test connection if connection config changed if (updates.connection) { await this.testConnection(dataSource); } this.emit('dataSourceUpdated', { dataSource }); return true; } catch (error) { this.emit('error', { operation: 'updateDataSource', error }); return false; } } async removeDataSource(dataSourceId: string): Promise<boolean> { try { const dataSource = this.dataSources.get(dataSourceId); if (!dataSource) { return false; } // Check if data source is used in any queries const dependentQueries = Array.from(this.queries.values()) .filter(q => q.datasources.includes(dataSourceId)); if (dependentQueries.length > 0) { throw new Error(`Cannot remove data source with ${dependentQueries.length} dependent queries`); } this.dataSources.delete(dataSourceId); this.emit('dataSourceRemoved', { dataSourceId }); return true; } catch (error) { this.emit('error', { operation: 'removeDataSource', error }); return false; } } async getDataSources(): Promise<DataSource[]> { return Array.from(this.dataSources.values()) .sort((a, b) => a.name.localeCompare(b.name)); } async getDataSource(dataSourceId: string): Promise<DataSource | undefined> { return this.dataSources.get(dataSourceId); } // Query Management async createQuery(query: Omit<AnalyticsQuery, 'id' | 'metadata'>): Promise<string> { try { const queryId = this.generateId(); const analyticsQuery: AnalyticsQuery = { id: queryId, metadata: { tags: [], owner: 'system', version: '1.0.0', createdAt: new Date(), updatedAt: new Date(), executionHistory: [] }, ...query }; // Validate query await this.validateQuery(analyticsQuery); this.queries.set(queryId, analyticsQuery); this.emit('queryCreated', { query: analyticsQuery }); return queryId; } catch (error) { this.emit('error', { operation: 'createQuery', error }); throw error; } } async updateQuery(queryId: string, updates: Partial<AnalyticsQuery>): Promise<boolean> { try { const query = this.queries.get(queryId); if (!query) { throw new Error(`Query ${queryId} not found`); } Object.assign(query, updates); query.metadata.updatedAt = new Date(); if (updates.query) { await this.validateQuery(query); } this.emit('queryUpdated', { query }); return true; } catch (error) { this.emit('error', { operation: 'updateQuery', error }); return false; } } async deleteQuery(queryId: string): Promise<boolean> { try { const query = this.queries.get(queryId); if (!query) { return false; } this.queries.delete(queryId); this.emit('queryDeleted', { queryId }); return true; } catch (error) { this.emit('error', { operation: 'deleteQuery', error }); return false; } } async getQuery(queryId: string): Promise<AnalyticsQuery | undefined> { return this.queries.get(queryId); } async getQueries(workspaceId?: string): Promise<AnalyticsQuery[]> { let queries = Array.from(this.queries.values()); if (workspaceId) { const workspace = this.workspaces.get(workspaceId); if (workspace) { queries = queries.filter(q => workspace.queries.includes(q.id)); } } return queries.sort((a, b) => b.metadata.updatedAt.getTime() - a.metadata.updatedAt.getTime()); } // Query Execution async executeQuery( queryId: string, parameters: Record<string, any> = {}, options: { userId?: string; timeout?: number; limit?: number; useCache?: boolean; } = {} ): Promise<string> { try { const query = this.queries.get(queryId); if (!query) { throw new Error(`Query ${queryId} not found`); } const executionId = this.generateId(); const execution: QueryExecution = { id: executionId, queryId, status: 'running', startTime: new Date(), parameters, results: { columns: [], rows: [], rowCount: 0, hasMore: false, metadata: { bytesScanned: 0, cacheHit: false, warnings: [] } }, metrics: { planningTime: 0, executionTime: 0, queueTime: 0, cpuTime: 0, memoryPeak: 0, diskSpilled: 0, networkIO: 0, cacheHits: 0, cacheMisses: 0 }, errors: [], cached: false, userId: options.userId || 'anonymous' }; this.executions.set(executionId, execution); this.emit('executionStarted', { execution }); // Execute query asynchronously this.processQuery(execution, query, options); return executionId; } catch (error) { this.emit('error', { operation: 'executeQuery', error }); throw error; } } async cancelExecution(executionId: string): Promise<boolean> { try { const execution = this.executions.get(executionId); if (!execution || execution.status !== 'running') { return false; } execution.status = 'cancelled'; execution.endTime = new Date(); execution.duration = execution.endTime.getTime() - execution.startTime.getTime(); this.emit('executionCancelled', { execution }); return true; } catch (error) { this.emit('error', { operation: 'cancelExecution', error }); return false; } } async getExecution(executionId: string): Promise<QueryExecution | undefined> { return this.executions.get(executionId); } async getExecutionHistory(queryId: string, limit: number = 50): Promise<QueryExecution[]> { return Array.from(this.executions.values()) .filter(e => e.queryId === queryId) .sort((a, b) => b.startTime.getTime() - a.startTime.getTime()) .slice(0, limit); } // Workspace Management async createWorkspace(workspace: Omit<AnalyticsWorkspace, 'id' | 'createdAt' | 'updatedAt'>): Promise<string> { try { const workspaceId = this.generateId(); const analyticsWorkspace: AnalyticsWorkspace = { id: workspaceId, createdAt: new Date(), updatedAt: new Date(), ...workspace }; this.workspaces.set(workspaceId, analyticsWorkspace); this.emit('workspaceCreated', { workspace: analyticsWorkspace }); return workspaceId; } catch (error) { this.emit('error', { operation: 'createWorkspace', error }); throw error; } } async updateWorkspace(workspaceId: string, updates: Partial<AnalyticsWorkspace>): Promise<boolean> { try { const workspace = this.workspaces.get(workspaceId); if (!workspace) { throw new Error(`Workspace ${workspaceId} not found`); } Object.assign(workspace, updates, { updatedAt: new Date() }); this.emit('workspaceUpdated', { workspace }); return true; } catch (error) { this.emit('error', { operation: 'updateWorkspace', error }); return false; } } async deleteWorkspace(workspaceId: string): Promise<boolean> { try { const workspace = this.workspaces.get(workspaceId); if (!workspace) { return false; } // Delete associated queries and dashboards for (const queryId of workspace.queries) { await this.deleteQuery(queryId); } for (const dashboardId of workspace.dashboards) { await this.deleteDashboard(dashboardId); } this.workspaces.delete(workspaceId); this.emit('workspaceDeleted', { workspaceId }); return true; } catch (error) { this.emit('error', { operation: 'deleteWorkspace', error }); return false; } } async getWorkspace(workspaceId: string): Promise<AnalyticsWorkspace | undefined> { return this.workspaces.get(workspaceId); } async getWorkspaces(userId?: string): Promise<AnalyticsWorkspace[]> { let workspaces = Array.from(this.workspaces.values()); if (userId) { workspaces = workspaces.filter(w => w.owner === userId || w.members.some(m => m.userId === userId) ); } return workspaces.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime()); } // Dashboard Management async createDashboard(dashboard: Omit<Dashboard, 'id' | 'createdAt' | 'updatedAt'>): Promise<string> { try { const dashboardId = this.generateId(); const analyticsDashboard: Dashboard = { id: dashboardId, createdAt: new Date(), updatedAt: new Date(), ...dashboard }; this.dashboards.set(dashboardId, analyticsDashboard); // Add to workspace const workspace = this.workspaces.get(dashboard.workspaceId); if (workspace) { workspace.dashboards.push(dashboardId); } this.emit('dashboardCreated', { dashboard: analyticsDashboard }); return dashboardId; } catch (error) { this.emit('error', { operation: 'createDashboard', error }); throw error; } } async updateDashboard(dashboardId: string, updates: Partial<Dashboard>): Promise<boolean> { try { const dashboard = this.dashboards.get(dashboardId); if (!dashboard) { throw new Error(`Dashboard ${dashboardId} not found`); } Object.assign(dashboard, updates, { updatedAt: new Date() }); this.emit('dashboardUpdated', { dashboard }); return true; } catch (error) { this.emit('error', { operation: 'updateDashboard', error }); return false; } } async deleteDashboard(dashboardId: string): Promise<boolean> { try { const dashboard = this.dashboards.get(dashboardId); if (!dashboard) { return false; } // Remove from workspace const workspace = this.workspaces.get(dashboard.workspaceId); if (workspace) { const index = workspace.dashboards.indexOf(dashboardId); if (index !== -1) { workspace.dashboards.splice(index, 1); } } this.dashboards.delete(dashboardId); this.emit('dashboardDeleted', { dashboardId }); return true; } catch (error) { this.emit('error', { operation: 'deleteDashboard', error }); return false; } } async getDashboard(dashboardId: string): Promise<Dashboard | undefined> { return this.dashboards.get(dashboardId); } async getDashboards(workspaceId?: string): Promise<Dashboard[]> { let dashboards = Array.from(this.dashboards.values()); if (workspaceId) { dashboards = dashboards.filter(d => d.workspaceId === workspaceId); } return dashboards.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime()); } // Analytics and Insights async getQueryAnalytics(queryId: string): Promise<{ executionCount: number; averageDuration: number; successRate: number; popularParameters: Record<string, number>; performanceTrend: { date: Date; duration: number }[]; errorAnalysis: { error: string; count: number }[]; }> { const executions = await this.getExecutionHistory(queryId, 1000); const executionCount = executions.length; const successfulExecutions = executions.filter(e => e.status === 'completed'); const averageDuration = successfulExecutions.length > 0 ? successfulExecutions.reduce((sum, e) => sum + (e.duration || 0), 0) / successfulExecutions.length : 0; const successRate = executionCount > 0 ? successfulExecutions.length / executionCount : 0; const parameterCounts: Record<string, number> = {}; executions.forEach(e => { Object.keys(e.parameters).forEach(param => { parameterCounts[param] = (parameterCounts[param] || 0) + 1; }); }); const performanceTrend = executions .filter(e => e.duration) .map(e => ({ date: e.startTime, duration: e.duration! })) .sort((a, b) => a.date.getTime() - b.date.getTime()); const errorCounts: Record<string, number> = {}; executions.forEach(e => { e.errors.forEach(error => { errorCounts[error.message] = (errorCounts[error.message] || 0) + 1; }); }); const errorAnalysis = Object.entries(errorCounts) .map(([error, count]) => ({ error, count })) .sort((a, b) => b.count - a.count); return { executionCount, averageDuration, successRate, popularParameters: parameterCounts, performanceTrend, errorAnalysis }; } async getSystemMetrics(): Promise<{ activeQueries: number; queuedQueries: number; cacheHitRate: number; averageQueryTime: number; errorRate: number; resourceUtilization: { cpu: number; memory: number; disk: number; network: number; }; dataSourceHealth: { [id: string]: 'online' | 'offline' | 'degraded' }; }> { const activeExecutions = Array.from(this.executions.values()) .filter(e => e.status === 'running'); const recentExecutions = Array.from(this.executions.values()) .filter(e => e.startTime > new Date(Date.now() - 24 * 60 * 60 * 1000)); // Last 24 hours const cacheHits = recentExecutions.reduce((sum, e) => sum + e.metrics.cacheHits, 0); const cacheMisses = recentExecutions.reduce((sum, e) => sum + e.metrics.cacheMisses, 0); const cacheHitRate = (cacheHits + cacheMisses) > 0 ? cacheHits / (cacheHits + cacheMisses) : 0; const completedExecutions = recentExecutions.filter(e => e.duration); const averageQueryTime = completedExecutions.length > 0 ? completedExecutions.reduce((sum, e) => sum + (e.duration || 0), 0) / completedExecutions.length : 0; const errorRate = recentExecutions.length > 0 ? recentExecutions.filter(e => e.status === 'failed').length / recentExecutions.length : 0; const dataSourceHealth: { [id: string]: 'online' | 'offline' | 'degraded' } = {}; for (const [id, dataSource] of this.dataSources.entries()) { dataSourceHealth[id] = dataSource.status; } return { activeQueries: activeExecutions.length, queuedQueries: 0, // Simplified cacheHitRate, averageQueryTime, errorRate, resourceUtilization: { cpu: Math.random() * 100, memory: Math.random() * 100, disk: Math.random() * 100, network: Math.random() * 100 }, dataSourceHealth }; } private async processQuery( execution: QueryExecution, query: AnalyticsQuery, options: any ): Promise<void> { try { const startTime = Date.now(); // Check cache first if (options.useCache !== false && query.cache.enabled) { const cachedResult = this.getCachedResult(query, execution.parameters); if (cachedResult) { execution.results = cachedResult.result; execution.cached = true; execution.status = 'completed'; execution.endTime = new Date(); execution.duration = Date.now() - execution.startTime.getTime(); execution.metrics.cacheHits = 1; this.emit('executionCompleted', { execution }); return; } } // Apply security policies const secureQuery = await this.securityManager.applySecurityPolicies(query, execution.userId); // Optimize query const optimizedQuery = await this.queryOptimizer.optimize(secureQuery); // Execute query const result = await this.executeQueryOnDataSources(optimizedQuery, execution.parameters, options); execution.results = result; execution.status = 'completed'; execution.endTime = new Date(); execution.duration = Date.now() - execution.startTime.getTime(); execution.metrics.executionTime = execution.duration; execution.metrics.cacheMisses = 1; // Cache result if enabled if (query.cache.enabled) { this.cacheResult(query, execution.parameters, result); } this.emit('executionCompleted', { execution }); } catch (error) { execution.status = 'failed'; execution.endTime = new Date(); execution.duration = Date.now() - execution.startTime.getTime(); execution.errors.push({ code: 'EXECUTION_ERROR', message: error.message, severity: 'error' }); this.emit('executionFailed', { execution, error }); } } private async executeQueryOnDataSources( query: AnalyticsQuery, parameters: Record<string, any>, options: any ): Promise<QueryResult> { // Simulate query execution await new Promise(resolve => setTimeout(resolve, Math.random() * 2000 + 500)); // Generate mock results const columns: ColumnInfo[] = [ { name: 'id', type: 'integer', nullable: false, semanticType: 'id' }, { name: 'name', type: 'string', nullable: false, semanticType: 'dimension' }, { name: 'value', type: 'float', nullable: true, semanticType: 'measure' }, { name: 'created_at', type: 'timestamp', nullable: false, semanticType: 'timestamp' } ]; const rows: any[][] = []; for (let i = 0; i < 100; i++) { rows.push([ i + 1, `Item ${i + 1}`, Math.random() * 1000, new Date(Date.now() - Math.random() * 365 * 24 * 60 * 60 * 1000) ]); } return { columns, rows, rowCount: rows.length, hasMore: false, metadata: { bytesScanned: 1024 * 1024, cacheHit: false, warnings: [] } }; } private async validateQuery(query: AnalyticsQuery): Promise<void> { // Basic validation if (!query.query.trim()) { throw new Error('Query cannot be empty'); } // Check data source existence for (const dataSourceId of query.datasources) { if (!this.dataSources.has(dataSourceId)) { throw new Error(`Data source ${dataSourceId} not found`); } } } private async testConnection(dataSource: DataSource): Promise<void> { // Simulate connection test await new Promise(resolve => setTimeout(resolve, 100)); if (Math.random() > 0.9) { // 10% failure rate throw new Error('Connection test failed'); } } private async refreshSchema(dataSource: DataSource): Promise<void> { // Simulate schema refresh await new Promise(resolve => setTimeout(resolve, 500)); dataSource.schema.lastRefreshed = new Date(); } private getCachedResult(query: AnalyticsQuery, parameters: Record<string, any>): CachedResult | undefined { const cacheKey = this.generateCacheKey(query, parameters); const cached = this.resultCache.get(cacheKey); if (cached && Date.now() - cached.timestamp.getTime() < query.cache.ttl) { return cached; } return undefined; } private cacheResult(query: AnalyticsQuery, parameters: Record<string, any>, result: QueryResult): void { const cacheKey = this.generateCacheKey(query, parameters); this.resultCache.set(cacheKey, { result, timestamp: new Date(), size: JSON.stringify(result).length }); } private generateCacheKey(query: AnalyticsQuery, parameters: Record<string, any>): string { return `${query.id}:${JSON.stringify(parameters)}`; } private startCacheEviction(): void { setInterval(() => { const now = Date.now(); for (const [key, cached] of this.resultCache.entries()) { if (now - cached.timestamp.getTime() > 3600000) { // 1 hour this.resultCache.delete(key); } } }, 5 * 60 * 1000); // Every 5 minutes } private startPerformanceMonitoring(): void { setInterval(() => { this.collectPerformanceMetrics(); }, 30000); // Every 30 seconds } private collectPerformanceMetrics(): void { // Collect and emit performance metrics const metrics = { activeExecutions: Array.from(this.executions.values()).filter(e => e.status === 'running').length, cacheSize: this.resultCache.size, dataSourceCount: this.dataSources.size, queryCount: this.queries.size }; this.emit('performanceMetrics', metrics); } private generateId(): string { return Math.random().toString(36).substring(2, 15); } } // Helper interfaces and classes interface CachedResult { result: QueryResult; timestamp: Date; size: number; } class QueryOptimizer { constructor(private config: AnalyticsEngineConfig) {} async optimize(query: AnalyticsQuery): Promise<AnalyticsQuery> { // Query optimization logic would go here return query; } } class SecurityManager { constructor(private config: any) {} async applySecurityPolicies(query: AnalyticsQuery, userId: string): Promise<AnalyticsQuery> { // Security policy application would go here return query; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Coder-RL/Claude_MCPServer_Dev1'

If you have feedback or need assistance with the MCP directory API, please join our Discord server