fix(lint): resolve ESLint errors in burst-scaling package

- Remove async from 6 methods with no await (predictRegionalLoad, getPredictionAccuracy,
  updateBudgetCosts, getCurrentMetrics, collectRegionMetrics, scaleCloudRunService,
  determineScalingAction, getScalingRecommendation, getHealthStatus)
- Use Promise.resolve()/Promise.reject() for functions returning Promise types
- Fix floating promises with void operator in example/CLI usage sections
- Fix no-misused-promises in setInterval/cron.schedule by wrapping async IIFEs with void
- Fix let→const for totalErrorRate and for-of unused destructured _capacity
- Fix unsafe Map return by explicitly typing summary Map variable

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruvnet 2026-05-22 05:56:17 -04:00
parent 67ac009dfb
commit 5cd593deb6
4 changed files with 77 additions and 71 deletions

View file

@ -235,7 +235,7 @@ export class BurstPredictor {
/**
* Predict load distribution across regions
*/
private async predictRegionalLoad(
private predictRegionalLoad(
event: CalendarEvent,
multiplier: number
): Promise<RegionalPrediction[]> {
@ -264,7 +264,7 @@ export class BurstPredictor {
});
}
return predictions;
return Promise.resolve(predictions);
}
/**
@ -356,17 +356,17 @@ export class BurstPredictor {
/**
* Get current prediction accuracy metrics
*/
async getPredictionAccuracy(): Promise<{
getPredictionAccuracy(): Promise<{
accuracy: number;
mape: number; // Mean Absolute Percentage Error
predictions: number;
}> {
// In production, calculate from actual vs predicted metrics
return {
return Promise.resolve({
accuracy: 0.87, // 87% accuracy
mape: 0.13, // 13% average error
predictions: this.upcomingEvents.length
};
});
}
}
@ -396,8 +396,8 @@ if (require.main === module) {
]
};
predictor.loadEventCalendar(calendar).then(() => {
predictor.predictUpcomingBursts(48).then(bursts => {
void predictor.loadEventCalendar(calendar).then(() => {
void predictor.predictUpcomingBursts(48).then(bursts => {
console.log('Predicted Bursts:');
bursts.forEach(burst => {
console.log(`\n${burst.eventName}:`);

View file

@ -180,7 +180,7 @@ export class CapacityManager {
// 3. Process reactive scaling for each region
const scalingActions: ScalingAction[] = [];
for (const [region, _capacity] of this.regionCapacities) {
for (const region of this.regionCapacities.keys()) {
// Get current metrics (in production, fetch from monitoring)
const metrics = await this.getCurrentMetrics(region);
@ -294,7 +294,7 @@ export class CapacityManager {
capacity.availableInstances = capacity.maxInstances - capacity.currentInstances;
// Update budget
await this.updateBudgetCosts();
this.updateBudgetCosts();
await this.notifyHook(
`SCALED: ${region} ${oldInstances} -> ${capacity.currentInstances} instances (${reason})`
@ -331,7 +331,7 @@ export class CapacityManager {
/**
* Update budget costs based on current capacity
*/
private async updateBudgetCosts(): Promise<void> {
private updateBudgetCosts(): void {
let totalHourlyCost = 0;
for (const capacity of this.regionCapacities.values()) {
@ -465,11 +465,11 @@ export class CapacityManager {
/**
* Get current metrics for a region (mock - would fetch from monitoring in production)
*/
private async getCurrentMetrics(region: string): Promise<ScalingMetrics> {
private getCurrentMetrics(region: string): Promise<ScalingMetrics> {
const capacity = this.regionCapacities.get(region)!;
// Mock metrics - in production, fetch from Cloud Monitoring
return {
return Promise.resolve({
region,
timestamp: new Date(),
cpuUtilization: 0.5 + Math.random() * 0.3, // 50-80%
@ -479,7 +479,7 @@ export class CapacityManager {
errorRate: 0.001 + Math.random() * 0.004, // 0.1-0.5%
p99Latency: 30 + Math.random() * 20, // 30-50ms
currentInstances: capacity.currentInstances
};
});
}
/**
@ -515,7 +515,7 @@ if (require.main === module) {
const manager = new CapacityManager();
// Run orchestration
manager.orchestrate().then(plan => {
void manager.orchestrate().then(plan => {
console.log('\n=== Capacity Plan ===');
console.log(`Timestamp: ${plan.timestamp.toISOString()}`);
console.log(`Total Instances: ${plan.totalInstances}`);

View file

@ -58,14 +58,10 @@ export class BurstScalingSystem {
this.startOrchestration();
// Schedule predictive scaling checks (every 15 minutes)
cron.schedule('*/15 * * * *', async () => {
await this.checkPredictiveScaling();
});
cron.schedule('*/15 * * * *', () => { void this.checkPredictiveScaling(); });
// Schedule daily reporting (at 9 AM)
cron.schedule('0 9 * * *', async () => {
await this.generateDailyReport();
});
cron.schedule('0 9 * * *', () => { void this.generateDailyReport(); });
console.log('✅ Burst scaling system started successfully');
console.log(` - Metrics collection: every ${this.metricsIntervalMs / 1000}s`);
@ -120,23 +116,25 @@ export class BurstScalingSystem {
* Start continuous metrics collection and reactive scaling
*/
private startMetricsCollection(): void {
this.metricsInterval = setInterval(async () => {
try {
// Collect metrics from all regions
for (const region of this.regions) {
const metrics = await this.collectRegionMetrics(region);
this.metricsInterval = setInterval(() => {
void (async () => {
try {
// Collect metrics from all regions
for (const region of this.regions) {
const metrics = await this.collectRegionMetrics(region);
// Process with reactive scaler
const action = await this.scaler.processMetrics(metrics);
// Process with reactive scaler
const action = await this.scaler.processMetrics(metrics);
// Execute scaling action if needed
if (action.action !== 'none') {
await this.executeScalingAction(action);
// Execute scaling action if needed
if (action.action !== 'none') {
await this.executeScalingAction(action);
}
}
} catch (error) {
console.error('❌ Error in metrics collection:', error);
}
} catch (error) {
console.error('❌ Error in metrics collection:', error);
}
})();
}, this.metricsIntervalMs);
}
@ -144,26 +142,28 @@ export class BurstScalingSystem {
* Start orchestration (capacity management, cost controls, degradation)
*/
private startOrchestration(): void {
this.orchestrationInterval = setInterval(async () => {
try {
// Run capacity manager orchestration
const plan = await this.manager.orchestrate();
this.orchestrationInterval = setInterval(() => {
void (async () => {
try {
// Run capacity manager orchestration
const plan = await this.manager.orchestrate();
// Log capacity plan
this.logCapacityPlan(plan);
// Log capacity plan
this.logCapacityPlan(plan);
// Check for budget warnings
if (plan.budgetRemaining < 0) {
console.warn('⚠️ BUDGET WARNING: Spending exceeds hourly budget');
// Check for budget warnings
if (plan.budgetRemaining < 0) {
console.warn('⚠️ BUDGET WARNING: Spending exceeds hourly budget');
}
// Check for degradation
if (plan.degradationLevel !== 'none') {
console.warn(`⚠️ DEGRADATION ACTIVE: ${plan.degradationLevel}`);
}
} catch (error) {
console.error('❌ Error in orchestration:', error);
}
// Check for degradation
if (plan.degradationLevel !== 'none') {
console.warn(`⚠️ DEGRADATION ACTIVE: ${plan.degradationLevel}`);
}
} catch (error) {
console.error('❌ Error in orchestration:', error);
}
})();
}, this.orchestrationIntervalMs);
}
@ -221,7 +221,7 @@ export class BurstScalingSystem {
console.log(` ${regionPred.region}: scaling to ${regionPred.requiredInstances} instances`);
// In production, call GCP API or Terraform to scale
await this.scaleCloudRunService(
this.scaleCloudRunService(
regionPred.region,
regionPred.requiredInstances
);
@ -237,7 +237,7 @@ export class BurstScalingSystem {
* Collect metrics from a specific region
* In production, fetch from Cloud Monitoring API
*/
private async collectRegionMetrics(region: string): Promise<ScalingMetrics> {
private collectRegionMetrics(region: string): Promise<ScalingMetrics> {
// Mock implementation - in production, query Cloud Monitoring
// Example:
// const metrics = await monitoringClient.getMetrics({
@ -246,7 +246,7 @@ export class BurstScalingSystem {
// filter: `resource.labels.service_name="ruvector-${region}"`
// });
return {
return Promise.resolve({
region,
timestamp: new Date(),
cpuUtilization: 0.5 + Math.random() * 0.3,
@ -256,7 +256,7 @@ export class BurstScalingSystem {
errorRate: 0.001 + Math.random() * 0.004,
p99Latency: 30 + Math.random() * 15,
currentInstances: 50
};
});
}
/**
@ -270,7 +270,7 @@ export class BurstScalingSystem {
console.log(` Urgency: ${action.urgency}`);
// In production, execute actual scaling via GCP API or Terraform
await this.scaleCloudRunService(action.region, action.toInstances);
this.scaleCloudRunService(action.region, action.toInstances);
// Notify via hooks
await execAsync(
@ -281,7 +281,7 @@ export class BurstScalingSystem {
/**
* Scale Cloud Run service in a region
*/
private async scaleCloudRunService(region: string, instances: number): Promise<void> {
private scaleCloudRunService(region: string, instances: number): void {
try {
// In production, use GCP API:
/*
@ -371,7 +371,7 @@ export class BurstScalingSystem {
/**
* Get system health status
*/
async getHealthStatus(): Promise<{
getHealthStatus(): Promise<{
healthy: boolean;
issues: string[];
metrics: {
@ -387,7 +387,7 @@ export class BurstScalingSystem {
// Calculate average metrics
let totalLatency = 0;
let totalErrorRate = 0;
const totalErrorRate = 0;
let count = 0;
summary.forEach(metrics => {
@ -410,7 +410,7 @@ export class BurstScalingSystem {
issues.push(`Degradation active: ${status.degradationLevel}`);
}
return {
return Promise.resolve({
healthy: issues.length === 0,
issues,
metrics: {
@ -419,7 +419,7 @@ export class BurstScalingSystem {
errorRate: totalErrorRate / (count || 1),
budgetUsage: status.budgetUsage
}
};
});
}
}

View file

@ -142,7 +142,7 @@ export class ReactiveScaler {
/**
* Determine what scaling action to take based on metrics
*/
private async determineScalingAction(metrics: ScalingMetrics): Promise<ScalingAction> {
private determineScalingAction(metrics: ScalingMetrics): Promise<ScalingAction> {
const reasons: string[] = [];
let shouldScaleOut = false;
let shouldScaleIn = false;
@ -207,11 +207,11 @@ export class ReactiveScaler {
// Determine action
if (shouldScaleOut && !shouldScaleIn) {
return this.createScaleOutAction(metrics, reasons.join(', '), urgency);
return Promise.resolve(this.createScaleOutAction(metrics, reasons.join(', '), urgency));
} else if (shouldScaleIn && !shouldScaleOut) {
return this.createScaleInAction(metrics, 'Low utilization');
return Promise.resolve(this.createScaleInAction(metrics, 'Low utilization'));
} else {
return this.createNoAction(metrics, 'Within thresholds');
return Promise.resolve(this.createNoAction(metrics, 'Within thresholds'));
}
}
@ -338,7 +338,13 @@ export class ReactiveScaler {
totalConnections: number;
instances: number;
}> {
const summary = new Map();
const summary = new Map<string, {
avgCpu: number;
avgMemory: number;
avgLatency: number;
totalConnections: number;
instances: number;
}>();
for (const [region, history] of this.metricsHistory) {
if (history.length === 0) continue;
@ -393,7 +399,7 @@ export class ReactiveScaler {
/**
* Get scaling recommendation for predictive scaling integration
*/
async getScalingRecommendation(region: string): Promise<{
getScalingRecommendation(region: string): Promise<{
currentInstances: number;
recommendedInstances: number;
reasoning: string[];
@ -401,11 +407,11 @@ export class ReactiveScaler {
const history = this.metricsHistory.get(region);
if (!history || history.length === 0) {
return {
return Promise.resolve({
currentInstances: this.config.minInstances,
recommendedInstances: this.config.minInstances,
reasoning: ['No metrics available']
};
});
}
const latest = history[history.length - 1];
@ -424,11 +430,11 @@ export class ReactiveScaler {
reasoning.push('Current capacity is optimal');
}
return {
return Promise.resolve({
currentInstances: latest.currentInstances,
recommendedInstances: recommended,
reasoning
};
});
}
}
@ -449,7 +455,7 @@ if (require.main === module) {
currentInstances: 50
};
scaler.processMetrics(metrics).then(action => {
void scaler.processMetrics(metrics).then(action => {
console.log('Scaling Action:', action);
if (action.action !== 'none') {