113 lines
2.5 KiB
Go
113 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// ============================================================================
|
|
// 💡 GO 09: MUSTERLÖSUNG (Goroutines & sync.WaitGroup)
|
|
// ============================================================================
|
|
|
|
// ServerMetric repräsentiert das Ergebnis eines Server-Health-Checks.
|
|
type ServerMetric struct {
|
|
ServerID string
|
|
LatencyMs int
|
|
Status string
|
|
Timestamp time.Time
|
|
}
|
|
|
|
// CheckServer prüft einen Server asynchron und meldet das Ergebnis via Channel.
|
|
func CheckServer(serverID string, wg *sync.WaitGroup, out chan<- ServerMetric) {
|
|
defer wg.Done()
|
|
|
|
status := "ONLINE"
|
|
latency := 15
|
|
|
|
if strings.HasPrefix(serverID, "offline-") {
|
|
status = "OFFLINE"
|
|
latency = 999
|
|
} else if strings.HasPrefix(serverID, "slow-") {
|
|
status = "DEGRADED"
|
|
latency = 250
|
|
}
|
|
|
|
metric := ServerMetric{
|
|
ServerID: serverID,
|
|
LatencyMs: latency,
|
|
Status: status,
|
|
Timestamp: time.Now(),
|
|
}
|
|
|
|
out <- metric
|
|
}
|
|
|
|
// BatchHealthCheck führt nebenläufige Server-Checks durch und synchronisiert sie via sync.WaitGroup.
|
|
func BatchHealthCheck(servers []string) []ServerMetric {
|
|
if len(servers) == 0 {
|
|
return []ServerMetric{}
|
|
}
|
|
|
|
var wg sync.WaitGroup
|
|
out := make(chan ServerMetric, len(servers))
|
|
|
|
for _, srv := range servers {
|
|
wg.Add(1)
|
|
go CheckServer(srv, &wg, out)
|
|
}
|
|
|
|
// Goroutine zum Schließen des Channels nach Abschluss aller Worker
|
|
go func() {
|
|
wg.Wait()
|
|
close(out)
|
|
}()
|
|
|
|
var results []ServerMetric
|
|
for metric := range out {
|
|
results = append(results, metric)
|
|
}
|
|
|
|
// Sortieren nach ServerID für deterministische Ausgabe
|
|
sort.Slice(results, func(i, j int) bool {
|
|
return results[i].ServerID < results[j].ServerID
|
|
})
|
|
|
|
return results
|
|
}
|
|
|
|
// ParallelTaskRunner führt generische Tasks parallel aus und sammelt Ergebnisse indexgetreu.
|
|
func ParallelTaskRunner(tasks []func() string) []string {
|
|
if len(tasks) == 0 {
|
|
return []string{}
|
|
}
|
|
|
|
results := make([]string, len(tasks))
|
|
var wg sync.WaitGroup
|
|
|
|
for i, task := range tasks {
|
|
wg.Add(1)
|
|
go func(idx int, t func() string) {
|
|
defer wg.Done()
|
|
results[idx] = t()
|
|
}(i, task)
|
|
}
|
|
|
|
wg.Wait()
|
|
return results
|
|
}
|
|
|
|
func main() {
|
|
fmt.Println("=== Go 09: Musterlösung ===")
|
|
|
|
serverList := []string{"srv-01", "slow-node-02", "srv-03", "offline-backup"}
|
|
metrics := BatchHealthCheck(serverList)
|
|
|
|
fmt.Printf("Ergebnis des Health-Checks (%d Server):\n", len(metrics))
|
|
for _, m := range metrics {
|
|
fmt.Printf(" • %-15s => Status: %-8s (Latenz: %3d ms) @ %s\n",
|
|
m.ServerID, m.Status, m.LatencyMs, m.Timestamp.Format("15:04:05.000"))
|
|
}
|
|
}
|