Mining/pkg/mining/stats_collector.go
Claude 27f10dd252
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
ax(mining): replace prose comments with usage examples in StatsCollector
AX Principle 2: comments must show concrete usage, not restate the type
signature in prose. StatsCollector and HTTPStatsConfig had three lines of
descriptive prose that added no information an agent couldn't infer from
the names alone.

Co-Authored-By: Charon <charon@lethean.io>
2026-04-02 10:53:15 +01:00

54 lines
1.5 KiB
Go

package mining
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
)
// var collector StatsCollector = &XMRigStatsCollector{...}
// metrics, err := collector.CollectStats(ctx)
type StatsCollector interface {
CollectStats(ctx context.Context) (*PerformanceMetrics, error)
}
// HTTPStatsConfig{Host: "127.0.0.1", Port: 8080, Endpoint: "/2/summary"}
type HTTPStatsConfig struct {
Host string
Port int
Endpoint string // e.g., "/2/summary" for XMRig, "/summary" for TT-Miner
}
// var summary XMRigSummary
// if err := FetchJSONStats(ctx, HTTPStatsConfig{Host: "127.0.0.1", Port: 8080, Endpoint: "/2/summary"}, &summary); err != nil { return err }
func FetchJSONStats[T any](ctx context.Context, config HTTPStatsConfig, target *T) error {
if config.Port == 0 {
return fmt.Errorf("API port is zero")
}
url := fmt.Sprintf("http://%s:%d%s", config.Host, config.Port, config.Endpoint)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
resp, err := getHTTPClient().Do(req)
if err != nil {
return fmt.Errorf("HTTP request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
io.Copy(io.Discard, resp.Body) // Drain body to allow connection reuse
return fmt.Errorf("unexpected status code %d", resp.StatusCode)
}
if err := json.NewDecoder(resp.Body).Decode(target); err != nil {
return fmt.Errorf("failed to decode response: %w", err)
}
return nil
}