2026-08-15 01:36:51 +08:00

72 lines
1.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package agent
import (
"context"
"math/rand"
"time"
"git.opencomputing.cn/yumoqing/host-metrics-collector/internal/model"
)
// collectFn 是某一指标组的采集函数。
type collectFn func() ([]model.Sample, error)
// runGroup 按固定间隔运行采集,并把样本投递到 out 通道。
//
// - 启动时加入随机 jitter(0 ~ interval/2),避免大量主机同秒上报(惊群)。
// - 每次采集带超时控制,超时或出错时记录错误并继续下一轮。
func runGroup(ctx context.Context, interval, timeout time.Duration, name string, fn collectFn, out chan<- model.Sample, errc chan<- error) {
// 首次延迟打散。
first := time.Duration(rand.Int63n(int64(interval / 2)))
timer := time.NewTimer(first)
defer timer.Stop()
for {
select {
case <-ctx.Done():
return
case <-timer.C:
}
samples, err := collectWithTimeout(ctx, timeout, fn)
if err != nil {
select {
case errc <- err:
default:
}
}
for _, s := range samples {
select {
case out <- s:
case <-ctx.Done():
return
}
}
timer.Reset(interval)
}
}
// collectWithTimeout 在超时约束下执行采集函数。
func collectWithTimeout(ctx context.Context, timeout time.Duration, fn collectFn) ([]model.Sample, error) {
type result struct {
samples []model.Sample
err error
}
ch := make(chan result, 1)
go func() {
samples, err := fn()
ch <- result{samples: samples, err: err}
}()
select {
case r := <-ch:
return r.samples, r.err
case <-ctx.Done():
return nil, ctx.Err()
case <-time.After(timeout):
return nil, context.DeadlineExceeded
}
}