Add resume grace period functionality and update system status
This commit is contained in:
		
							
								
								
									
										77
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								main.go
									
									
									
									
									
								
							| @@ -23,16 +23,17 @@ import ( | ||||
|  | ||||
| const ( | ||||
| 	checkInterval     = 10 * time.Second | ||||
| 	monitoringPeriod = 5 * time.Minute | ||||
| 	cpuThreshold     = 20.0    // percentage | ||||
| 	gpuThreshold     = 20.0    // percentage | ||||
| 	diskThreshold    = 5 * 1024 * 1024    // 5 MB/s | ||||
| 	networkThreshold = 1 * 1024 * 1024    // 1 MB/s | ||||
| 	httpPort         = 8081 | ||||
| 	monitoringPeriod  = 5 * time.Minute | ||||
| 	resumeGracePeriod = 5 * time.Minute // Time to wait after resume before allowing sleep again | ||||
| 	cpuThreshold      = 20.0            // percentage | ||||
| 	gpuThreshold      = 20.0            // percentage | ||||
| 	diskThreshold     = 5 * 1024 * 1024 // 5 MB/s | ||||
| 	networkThreshold  = 1 * 1024 * 1024 // 1 MB/s | ||||
| 	httpPort          = 8081 | ||||
| ) | ||||
|  | ||||
| type ResourceUsage struct { | ||||
| 	Timestamp       time.Time `json:"timestamp"` | ||||
| 	Timestamp      time.Time `json:"timestamp"` | ||||
| 	CpuUsage       float64   `json:"cpu_usage"` | ||||
| 	GpuUsage       float64   `json:"gpu_usage"` | ||||
| 	GpuAvailable   bool      `json:"gpu_available"` | ||||
| @@ -43,14 +44,18 @@ type ResourceUsage struct { | ||||
| } | ||||
|  | ||||
| type SystemStatus struct { | ||||
| 	CurrentUsage ResourceUsage `json:"current_usage"` | ||||
| 	Blockers    []string      `json:"sleep_blockers"` | ||||
| 	CurrentUsage  ResourceUsage `json:"current_usage"` | ||||
| 	Blockers      []string      `json:"sleep_blockers"` | ||||
| 	InGracePeriod bool          `json:"in_grace_period,omitempty"` | ||||
| 	GraceTimeLeft string        `json:"grace_time_left,omitempty"` | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	currentStatus SystemStatus | ||||
| 	statusMutex   sync.RWMutex | ||||
| 	nvmlAvailable bool | ||||
| 	currentStatus  SystemStatus | ||||
| 	statusMutex    sync.RWMutex | ||||
| 	nvmlAvailable  bool | ||||
| 	lastResumeTime time.Time // Track when the system last resumed from sleep | ||||
| 	lastTickTime   time.Time // Track when we last processed a tick | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| @@ -95,7 +100,8 @@ func main() { | ||||
| 	log.Printf("- Network I/O < %.1f MB/s\n", float64(networkThreshold)/(1024*1024)) | ||||
| 	log.Printf("- No active SSH connections\n") | ||||
| 	log.Printf("- No active user sessions\n") | ||||
| 	log.Printf("Over the last %v\n", monitoringPeriod) | ||||
| 	log.Printf("- Over the last %v\n", monitoringPeriod) | ||||
| 	log.Printf("- System will not suspend for %v after resuming from sleep\n", resumeGracePeriod) | ||||
| 	log.Printf("HTTP status endpoint available at http://localhost:%d/status\n", httpPort) | ||||
| 	log.Printf("Press Ctrl+C to exit\n") | ||||
|  | ||||
| @@ -109,6 +115,19 @@ mainLoop: | ||||
| 			cancel() | ||||
| 			break mainLoop | ||||
| 		case <-ticker.C: | ||||
| 			now := time.Now() | ||||
|  | ||||
| 			// Check if we just resumed from sleep | ||||
| 			if !lastTickTime.IsZero() { | ||||
| 				gap := now.Sub(lastTickTime) | ||||
| 				// If there was a significant gap, probably resumed from sleep | ||||
| 				if gap > (checkInterval*3) && gap < time.Hour { | ||||
| 					log.Printf("Detected system resume after gap of %v", gap) | ||||
| 					lastResumeTime = now | ||||
| 				} | ||||
| 			} | ||||
| 			lastTickTime = now | ||||
|  | ||||
| 			usage := getCurrentUsage() | ||||
| 			usageHistory = append(usageHistory, usage) | ||||
|  | ||||
| @@ -151,6 +170,19 @@ mainLoop: | ||||
| 	log.Println("Goodbye!") | ||||
| } | ||||
|  | ||||
| // Function to check if we're within the resume grace period | ||||
| func isInsideResumeGracePeriod() bool { | ||||
| 	return !lastResumeTime.IsZero() && time.Since(lastResumeTime) < resumeGracePeriod | ||||
| } | ||||
|  | ||||
| // Function to calculate time left in grace period | ||||
| func timeLeftInGracePeriod() time.Duration { | ||||
| 	if !isInsideResumeGracePeriod() { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	return resumeGracePeriod - time.Since(lastResumeTime) | ||||
| } | ||||
|  | ||||
| func startHTTPServer(ctx context.Context) *http.Server { | ||||
| 	srv := &http.Server{ | ||||
| 		Addr: fmt.Sprintf(":%d", httpPort), | ||||
| @@ -182,6 +214,18 @@ func updateSystemStatus(current ResourceUsage, history []ResourceUsage) { | ||||
| 	currentStatus.CurrentUsage = current | ||||
| 	currentStatus.Blockers = []string{} | ||||
|  | ||||
| 	// Add grace period info to status | ||||
| 	if isInsideResumeGracePeriod() { | ||||
| 		timeLeft := timeLeftInGracePeriod() | ||||
| 		currentStatus.InGracePeriod = true | ||||
| 		currentStatus.GraceTimeLeft = timeLeft.Round(time.Second).String() | ||||
| 		currentStatus.Blockers = append(currentStatus.Blockers, | ||||
| 			fmt.Sprintf("Resume grace period: %v remaining", timeLeft.Round(time.Second))) | ||||
| 	} else { | ||||
| 		currentStatus.InGracePeriod = false | ||||
| 		currentStatus.GraceTimeLeft = "" | ||||
| 	} | ||||
|  | ||||
| 	if len(history) >= 2 { | ||||
| 		// Calculate rates using last two samples | ||||
| 		duration := history[len(history)-1].Timestamp.Sub(history[len(history)-2].Timestamp).Seconds() | ||||
| @@ -224,7 +268,7 @@ func updateSystemStatus(current ResourceUsage, history []ResourceUsage) { | ||||
|  | ||||
| func getCurrentUsage() ResourceUsage { | ||||
| 	usage := ResourceUsage{ | ||||
| 		Timestamp:     time.Now(), | ||||
| 		Timestamp:    time.Now(), | ||||
| 		GpuAvailable: nvmlAvailable, | ||||
| 	} | ||||
|  | ||||
| @@ -332,6 +376,11 @@ func getActiveUserCount() (int, error) { | ||||
| } | ||||
|  | ||||
| func isSystemIdle(history []ResourceUsage) bool { | ||||
| 	// Don't allow sleep during grace period after resume | ||||
| 	if isInsideResumeGracePeriod() { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	if len(history) < 2 { | ||||
| 		return false | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user