From c52fea2fec540ba12f9c066bb5be9c4537593b64 Mon Sep 17 00:00:00 2001 From: Michael Chus Date: Sat, 28 Feb 2026 15:21:49 +0300 Subject: [PATCH] collector/redfish: emit critical warmup branch and eta progress --- internal/collector/redfish.go | 38 +++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/internal/collector/redfish.go b/internal/collector/redfish.go index 78c2607..7aa6e0f 100644 --- a/internal/collector/redfish.go +++ b/internal/collector/redfish.go @@ -82,10 +82,12 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre managerPaths := c.discoverMemberPaths(ctx, client, req, baseURL, "/redfish/v1/Managers", "/redfish/v1/Managers/1") criticalPaths := redfishCriticalEndpoints(systemPaths, chassisPaths, managerPaths) criticalClient := c.httpClientWithTimeout(req, redfishCriticalRequestTimeout()) - criticalWarmDocs, criticalWarmErrs := c.collectCriticalRedfishDocsSequential(ctx, criticalClient, req, baseURL, criticalPaths) - if emit != nil { emit(Progress{Status: "running", Progress: 30, Message: "Redfish: чтение структуры Redfish..."}) + } + criticalWarmDocs, criticalWarmErrs := c.collectCriticalRedfishDocsSequential(ctx, criticalClient, req, baseURL, criticalPaths, emit) + + if emit != nil { emit(Progress{Status: "running", Progress: 55, Message: "Redfish: подготовка snapshot..."}) emit(Progress{Status: "running", Progress: 80, Message: "Redfish: подготовка расширенного snapshot..."}) emit(Progress{Status: "running", Progress: 90, Message: "Redfish: сбор расширенного snapshot..."}) @@ -1330,10 +1332,20 @@ func (c *RedfishConnector) getJSONWithRetry(ctx context.Context, client *http.Cl return nil, lastErr } -func (c *RedfishConnector) collectCriticalRedfishDocsSequential(ctx context.Context, client *http.Client, req Request, baseURL string, paths []string) (map[string]interface{}, map[string]string) { +func (c *RedfishConnector) collectCriticalRedfishDocsSequential(ctx context.Context, client *http.Client, req Request, baseURL string, paths []string, emit ProgressFn) (map[string]interface{}, map[string]string) { docs := make(map[string]interface{}) errs := make(map[string]string) - for _, p := range paths { + start := time.Now() + total := len(paths) + for i, p := range paths { + if emit != nil && total > 0 { + progress := 30 + int(float64(i)*24.0/float64(total)) + emit(Progress{ + Status: "running", + Progress: progress, + Message: fmt.Sprintf("Redfish critical (%d/%d, ETA≈%s): %s", i+1, total, formatETA(estimateCriticalWarmupETA(start, i, total, client.Timeout)), compactProgressPath(p)), + }) + } doc, err := c.getJSONWithRetry(ctx, client, req, baseURL, p, redfishCriticalRetryAttempts(), redfishCriticalRetryBackoff()) if err != nil { errs[p] = err.Error() @@ -1350,6 +1362,24 @@ func (c *RedfishConnector) collectCriticalRedfishDocsSequential(ctx context.Cont return docs, errs } +func estimateCriticalWarmupETA(start time.Time, processed, total int, requestTimeout time.Duration) time.Duration { + if total <= 0 || processed >= total { + return 0 + } + remaining := total - processed + if processed <= 0 { + if requestTimeout <= 0 { + requestTimeout = 10 * time.Second + } + return time.Duration(remaining) * requestTimeout + } + elapsed := time.Since(start) + if elapsed <= 0 { + return 0 + } + return time.Duration(float64(elapsed) * float64(remaining) / float64(processed)) +} + func (c *RedfishConnector) collectCriticalCollectionMembersSequential(ctx context.Context, client *http.Client, req Request, baseURL, collectionPath string, collectionDoc map[string]interface{}) (map[string]interface{}, bool) { refs, ok := collectionDoc["Members"].([]interface{}) if !ok || len(refs) == 0 {