mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 22:06:38 +08:00
943818f7d4
将 OpenFlare 与平台业务的数据访问从 model 与 apps 直连迁入 repository, model 仅保留实体与无 IO 规则;补充 code-check 架构守卫与开发规范。
95 lines
2.6 KiB
Go
95 lines
2.6 KiB
Go
// Package main is a manual smoke tool for ClickHouse app write path.
|
|
// Usage (from repo root, with config.yaml and Docker CH up):
|
|
//
|
|
// go run ./scripts/live_ch_smoke
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/Rain-kl/Wavelet/internal/repository"
|
|
|
|
"github.com/Rain-kl/Wavelet/internal/apps/openflare/chwriter"
|
|
db "github.com/Rain-kl/Wavelet/internal/infra/persistence"
|
|
"github.com/Rain-kl/Wavelet/internal/model"
|
|
)
|
|
|
|
const (
|
|
flushWaitTimeout = 45 * time.Second
|
|
listLimit = 5
|
|
pollInterval = 2 * time.Second
|
|
)
|
|
|
|
func main() {
|
|
if err := run(); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func run() error {
|
|
if !db.ChConnReady() {
|
|
return fmt.Errorf("ChConn not ready — check config.yaml clickhouse.enabled")
|
|
}
|
|
ctx := context.Background()
|
|
chwriter.Init(ctx)
|
|
defer func() { _ = chwriter.Stop(ctx) }()
|
|
|
|
now := time.Now().UTC()
|
|
nodeID := "e2e-app-" + now.Format("150405")
|
|
if err := repository.InsertOpenFlareMetricSnapshot(ctx, &model.OpenFlareMetricSnapshot{
|
|
NodeID: nodeID, CapturedAt: now, CPUUsagePercent: 41.2,
|
|
MemoryUsedBytes: 123, MemoryTotalBytes: 1000,
|
|
StorageUsedBytes: 456, StorageTotalBytes: 2000,
|
|
DiskReadBytes: 11, DiskWriteBytes: 22, NetworkRxBytes: 33, NetworkTxBytes: 44,
|
|
}); err != nil {
|
|
return fmt.Errorf("insert: %w", err)
|
|
}
|
|
fmt.Println("queued", nodeID)
|
|
|
|
if err := waitForSnapshot(ctx, nodeID, now); err != nil {
|
|
return err
|
|
}
|
|
if err := assertLatestIncludes(ctx, nodeID, now); err != nil {
|
|
return err
|
|
}
|
|
for _, s := range chwriter.WriterStats() {
|
|
fmt.Printf("writer %s running=%v depth=%d drops=%d flush_err=%d\n",
|
|
s.Name, s.Running, s.Depth, s.Drops, s.FlushErrors)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func waitForSnapshot(ctx context.Context, nodeID string, now time.Time) error {
|
|
deadline := time.Now().Add(flushWaitTimeout)
|
|
for time.Now().Before(deadline) {
|
|
rows, err := repository.ListOpenFlareMetricSnapshotsSince(ctx, nodeID, now.Add(-time.Minute), listLimit)
|
|
if err != nil {
|
|
return fmt.Errorf("list: %w", err)
|
|
}
|
|
if len(rows) > 0 {
|
|
fmt.Printf("OK flushed id=%d cpu=%.1f\n", rows[0].ID, rows[0].CPUUsagePercent)
|
|
return nil
|
|
}
|
|
time.Sleep(pollInterval)
|
|
}
|
|
return fmt.Errorf("not flushed within timeout")
|
|
}
|
|
|
|
func assertLatestIncludes(ctx context.Context, nodeID string, now time.Time) error {
|
|
latest, err := repository.ListOpenFlareLatestMetricSnapshotsSince(ctx, "", now.Add(-time.Hour))
|
|
if err != nil {
|
|
return fmt.Errorf("latest: %w", err)
|
|
}
|
|
for _, r := range latest {
|
|
if r != nil && r.NodeID == nodeID {
|
|
fmt.Println("OK latest-per-node includes node")
|
|
return nil
|
|
}
|
|
}
|
|
return fmt.Errorf("latest-per-node missing node %s", nodeID)
|
|
}
|