Mining/pkg/mining/stats_collector.go
Claude 599603e2f4
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
ax(mining): replace prose comment with usage example on FetchJSONStats
AX principle 2: comments show HOW with real values, not what the
signature already says. The old comment restated the function's
prose description; replaced with a concrete call site example.

Co-Authored-By: Charon <charon@lethean.io>
2026-04-02 09:03:17 +01:00

56 lines
1.6 KiB
Go

package mining
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
)
// StatsCollector defines the interface for collecting miner statistics.
// This allows different miner types to implement their own stats collection logic
// while sharing common HTTP fetching infrastructure.
type StatsCollector interface {
// CollectStats fetches and returns performance metrics from the miner.
CollectStats(ctx context.Context) (*PerformanceMetrics, error)
}
// HTTPStatsConfig holds configuration for HTTP-based stats collection.
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
}