Open source vector database with HNSW indexing, graph relationships, and metadata facets. Features CLI with professional augmentation registry integration for discovering extensions and capabilities.
261 lines
No EOL
10 KiB
JavaScript
261 lines
No EOL
10 KiB
JavaScript
/**
|
|
* Intelligent cache auto-configuration system
|
|
* Adapts cache settings based on environment, usage patterns, and storage type
|
|
*/
|
|
export class CacheAutoConfigurator {
|
|
constructor() {
|
|
this.stats = {
|
|
totalQueries: 0,
|
|
repeatQueries: 0,
|
|
avgQueryTime: 50,
|
|
memoryPressure: 0,
|
|
storageType: 'memory',
|
|
isDistributed: false,
|
|
changeFrequency: 0,
|
|
readWriteRatio: 10,
|
|
};
|
|
this.configHistory = [];
|
|
this.lastOptimization = 0;
|
|
}
|
|
/**
|
|
* Auto-detect optimal cache configuration based on current conditions
|
|
*/
|
|
autoDetectOptimalConfig(storageConfig, currentStats) {
|
|
// Update stats with current information
|
|
if (currentStats) {
|
|
this.stats = { ...this.stats, ...currentStats };
|
|
}
|
|
// Detect environment characteristics
|
|
this.detectEnvironment(storageConfig);
|
|
// Generate optimal configuration
|
|
const result = this.generateOptimalConfig();
|
|
// Store for learning
|
|
this.configHistory.push(result);
|
|
this.lastOptimization = Date.now();
|
|
return result;
|
|
}
|
|
/**
|
|
* Dynamically adjust configuration based on runtime performance
|
|
*/
|
|
adaptConfiguration(currentConfig, performanceMetrics) {
|
|
const reasoning = [];
|
|
let needsUpdate = false;
|
|
// Check if we should update (don't over-optimize)
|
|
if (Date.now() - this.lastOptimization < 60000) {
|
|
return null; // Wait at least 1 minute between optimizations
|
|
}
|
|
// Analyze performance patterns
|
|
const adaptations = {};
|
|
// Low hit rate → adjust cache size or TTL
|
|
if (performanceMetrics.hitRate < 0.3) {
|
|
if (performanceMetrics.externalChangesDetected > 5) {
|
|
// Too many external changes → shorter TTL
|
|
adaptations.maxAge = Math.max(60000, currentConfig.maxAge * 0.7);
|
|
reasoning.push('Reduced cache TTL due to frequent external changes');
|
|
needsUpdate = true;
|
|
}
|
|
else {
|
|
// Expand cache size for better hit rate
|
|
adaptations.maxSize = Math.min(500, (currentConfig.maxSize || 100) * 1.5);
|
|
reasoning.push('Increased cache size due to low hit rate');
|
|
needsUpdate = true;
|
|
}
|
|
}
|
|
// High hit rate but slow responses → might need cache warming
|
|
if (performanceMetrics.hitRate > 0.8 && performanceMetrics.avgResponseTime > 100) {
|
|
reasoning.push('High hit rate but slow responses - consider cache warming');
|
|
}
|
|
// Memory pressure → reduce cache size
|
|
if (performanceMetrics.memoryUsage > 100 * 1024 * 1024) { // 100MB
|
|
adaptations.maxSize = Math.max(20, (currentConfig.maxSize || 100) * 0.7);
|
|
reasoning.push('Reduced cache size due to memory pressure');
|
|
needsUpdate = true;
|
|
}
|
|
// Recent external changes → adaptive TTL
|
|
if (performanceMetrics.timeSinceLastChange < 30000) { // 30 seconds
|
|
adaptations.maxAge = Math.max(30000, currentConfig.maxAge * 0.8);
|
|
reasoning.push('Shortened TTL due to recent external changes');
|
|
needsUpdate = true;
|
|
}
|
|
if (!needsUpdate) {
|
|
return null;
|
|
}
|
|
const newCacheConfig = {
|
|
...currentConfig,
|
|
...adaptations
|
|
};
|
|
const newRealtimeConfig = this.calculateRealtimeConfig();
|
|
return {
|
|
cacheConfig: newCacheConfig,
|
|
realtimeConfig: newRealtimeConfig,
|
|
reasoning
|
|
};
|
|
}
|
|
/**
|
|
* Get recommended configuration for specific use case
|
|
*/
|
|
getRecommendedConfig(useCase) {
|
|
const configs = {
|
|
'high-consistency': {
|
|
cache: { maxAge: 120000, maxSize: 50 },
|
|
realtime: { interval: 15000, enabled: true },
|
|
reasoning: ['Optimized for data consistency and real-time updates']
|
|
},
|
|
'balanced': {
|
|
cache: { maxAge: 300000, maxSize: 100 },
|
|
realtime: { interval: 30000, enabled: true },
|
|
reasoning: ['Balanced performance and consistency']
|
|
},
|
|
'performance-first': {
|
|
cache: { maxAge: 600000, maxSize: 200 },
|
|
realtime: { interval: 60000, enabled: true },
|
|
reasoning: ['Optimized for maximum cache performance']
|
|
}
|
|
};
|
|
const config = configs[useCase];
|
|
return {
|
|
cacheConfig: {
|
|
enabled: true,
|
|
...config.cache
|
|
},
|
|
realtimeConfig: {
|
|
updateIndex: true,
|
|
updateStatistics: true,
|
|
...config.realtime
|
|
},
|
|
reasoning: config.reasoning
|
|
};
|
|
}
|
|
/**
|
|
* Learn from usage patterns and improve recommendations
|
|
*/
|
|
learnFromUsage(usageData) {
|
|
// Update internal stats for better future recommendations
|
|
this.stats.totalQueries += usageData.totalQueries;
|
|
this.stats.repeatQueries += usageData.cacheHits;
|
|
this.stats.avgQueryTime = (this.stats.avgQueryTime + usageData.responseTime) / 2;
|
|
this.stats.changeFrequency = usageData.dataChanges / (usageData.timeWindow / 60000);
|
|
// Calculate read/write ratio
|
|
const writes = usageData.dataChanges;
|
|
const reads = usageData.totalQueries;
|
|
this.stats.readWriteRatio = reads > 0 ? reads / Math.max(writes, 1) : 10;
|
|
}
|
|
detectEnvironment(storageConfig) {
|
|
// Detect storage type
|
|
if (storageConfig?.s3Storage || storageConfig?.customS3Storage) {
|
|
this.stats.storageType = 's3';
|
|
this.stats.isDistributed = true;
|
|
}
|
|
else if (storageConfig?.forceFileSystemStorage) {
|
|
this.stats.storageType = 'filesystem';
|
|
}
|
|
else if (storageConfig?.forceMemoryStorage) {
|
|
this.stats.storageType = 'memory';
|
|
}
|
|
else {
|
|
// Auto-detect browser vs Node.js
|
|
this.stats.storageType = typeof window !== 'undefined' ? 'opfs' : 'filesystem';
|
|
}
|
|
// Detect distributed mode indicators
|
|
this.stats.isDistributed = this.stats.isDistributed ||
|
|
Boolean(storageConfig?.s3Storage || storageConfig?.customS3Storage);
|
|
}
|
|
generateOptimalConfig() {
|
|
const reasoning = [];
|
|
// Base configuration
|
|
let cacheConfig = {
|
|
enabled: true,
|
|
maxSize: 100,
|
|
maxAge: 300000, // 5 minutes
|
|
hitCountWeight: 0.3
|
|
};
|
|
let realtimeConfig = {
|
|
enabled: false,
|
|
interval: 60000,
|
|
updateIndex: true,
|
|
updateStatistics: true
|
|
};
|
|
// Adjust for storage type
|
|
if (this.stats.storageType === 's3' || this.stats.isDistributed) {
|
|
cacheConfig.maxAge = 180000; // 3 minutes for distributed
|
|
realtimeConfig.enabled = true;
|
|
realtimeConfig.interval = 30000; // 30 seconds
|
|
reasoning.push('Distributed storage detected - enabled real-time updates');
|
|
reasoning.push('Reduced cache TTL for distributed consistency');
|
|
}
|
|
// Adjust for read/write patterns
|
|
if (this.stats.readWriteRatio > 20) {
|
|
// Read-heavy workload
|
|
cacheConfig.maxSize = Math.min(300, (cacheConfig.maxSize || 100) * 2);
|
|
cacheConfig.maxAge = Math.min(900000, (cacheConfig.maxAge || 300000) * 1.5); // Up to 15 minutes
|
|
reasoning.push('Read-heavy workload detected - increased cache size and TTL');
|
|
}
|
|
else if (this.stats.readWriteRatio < 5) {
|
|
// Write-heavy workload
|
|
cacheConfig.maxSize = Math.max(50, (cacheConfig.maxSize || 100) * 0.7);
|
|
cacheConfig.maxAge = Math.max(60000, (cacheConfig.maxAge || 300000) * 0.6);
|
|
reasoning.push('Write-heavy workload detected - reduced cache size and TTL');
|
|
}
|
|
// Adjust for change frequency
|
|
if (this.stats.changeFrequency > 10) { // More than 10 changes per minute
|
|
realtimeConfig.interval = Math.max(10000, realtimeConfig.interval * 0.5);
|
|
cacheConfig.maxAge = Math.max(30000, (cacheConfig.maxAge || 300000) * 0.5);
|
|
reasoning.push('High change frequency detected - increased update frequency');
|
|
}
|
|
// Memory constraints
|
|
if (this.detectMemoryConstraints()) {
|
|
cacheConfig.maxSize = Math.max(20, (cacheConfig.maxSize || 100) * 0.6);
|
|
reasoning.push('Memory constraints detected - reduced cache size');
|
|
}
|
|
// Performance optimization
|
|
if (this.stats.avgQueryTime > 200) {
|
|
cacheConfig.maxSize = Math.min(500, (cacheConfig.maxSize || 100) * 1.5);
|
|
reasoning.push('Slow queries detected - increased cache size');
|
|
}
|
|
return {
|
|
cacheConfig,
|
|
realtimeConfig,
|
|
reasoning
|
|
};
|
|
}
|
|
calculateRealtimeConfig() {
|
|
return {
|
|
enabled: this.stats.isDistributed || this.stats.changeFrequency > 1,
|
|
interval: this.stats.isDistributed ? 30000 : 60000,
|
|
updateIndex: true,
|
|
updateStatistics: true
|
|
};
|
|
}
|
|
detectMemoryConstraints() {
|
|
// Simple heuristic for memory constraints
|
|
try {
|
|
if (typeof performance !== 'undefined' && 'memory' in performance) {
|
|
const memInfo = performance.memory;
|
|
return memInfo.usedJSHeapSize > memInfo.jsHeapSizeLimit * 0.8;
|
|
}
|
|
}
|
|
catch (e) {
|
|
// Ignore errors
|
|
}
|
|
// Default assumption for constrained environments
|
|
return false;
|
|
}
|
|
/**
|
|
* Get human-readable explanation of current configuration
|
|
*/
|
|
getConfigExplanation(config) {
|
|
const lines = [
|
|
'🤖 Brainy Auto-Configuration:',
|
|
'',
|
|
`📊 Cache: ${config.cacheConfig.maxSize} queries, ${config.cacheConfig.maxAge / 1000}s TTL`,
|
|
`🔄 Updates: ${config.realtimeConfig.enabled ? `Every ${(config.realtimeConfig.interval || 30000) / 1000}s` : 'Disabled'}`,
|
|
'',
|
|
'🎯 Optimizations applied:'
|
|
];
|
|
config.reasoning.forEach(reason => {
|
|
lines.push(` • ${reason}`);
|
|
});
|
|
return lines.join('\n');
|
|
}
|
|
}
|
|
//# sourceMappingURL=cacheAutoConfig.js.map
|