85 lines
2.6 KiB
85 lines
2.6 KiB
package stages
|
|
|
|
import (
|
|
"fmt"
|
|
"gitea.anxinyun.cn/container/common_models"
|
|
"gitea.anxinyun.cn/container/common_utils/configLoad"
|
|
"log"
|
|
"time"
|
|
)
|
|
|
|
// 阶段处理
|
|
type Stage struct {
|
|
Name string
|
|
In <-chan []*common_models.ProcessData
|
|
processFuncs []func([]*common_models.ProcessData) []*common_models.ProcessData
|
|
Out chan []*common_models.ProcessData
|
|
execOver chan bool //阶段执行完毕,用以排查超时
|
|
}
|
|
|
|
func NewStage(name string) *Stage {
|
|
stageBufSize := configLoad.LoadConfig().GetInt64("performance.node.stageBufSize")
|
|
|
|
return &Stage{
|
|
Name: name,
|
|
processFuncs: make([]func([]*common_models.ProcessData) []*common_models.ProcessData, 0),
|
|
In: make(<-chan []*common_models.ProcessData, stageBufSize),
|
|
Out: make(chan []*common_models.ProcessData, stageBufSize),
|
|
execOver: make(chan bool, 1),
|
|
}
|
|
}
|
|
|
|
func (s *Stage) StageRun() <-chan []*common_models.ProcessData {
|
|
go func() {
|
|
defer func() {
|
|
close(s.Out)
|
|
log.Printf("[%s]关闭out", s.Name)
|
|
}()
|
|
|
|
for n := range s.In {
|
|
log.Printf("[%s]接收数据 In[%p] 通道长度=%d/%d", s.Name, s.In, len(s.In), cap(s.In))
|
|
result := s.process(n)
|
|
s.Out <- result
|
|
}
|
|
log.Printf("%s over", s.Name)
|
|
}()
|
|
|
|
return s.Out
|
|
}
|
|
|
|
func (s *Stage) AddProcess(fun func([]*common_models.ProcessData) []*common_models.ProcessData) {
|
|
s.processFuncs = append(s.processFuncs, fun)
|
|
}
|
|
|
|
func (s *Stage) process(data []*common_models.ProcessData) []*common_models.ProcessData {
|
|
go s.handlerTimeOutCheck(s.Name, "批量处理耗时跟踪")
|
|
|
|
for _, processFunc := range s.processFuncs {
|
|
//tag := fmt.Sprintf("%d/%d", i+1, len(s.processFuncs))
|
|
log.Printf("stage[%s] start, len(data)=%d", s.Name, len(data))
|
|
func() {
|
|
defer timeCost(s.Name, fmt.Sprintf("ProcessData数组元素个数[%d]", len(data)), time.Now())
|
|
data = processFunc(data)
|
|
}()
|
|
log.Printf("stage[%s] over, len(data)=%d", s.Name, len(data))
|
|
}
|
|
|
|
s.execOver <- true
|
|
return data
|
|
}
|
|
|
|
func (s *Stage) handlerTimeOutCheck(stageName, deviceId string) {
|
|
stageTimeout := configLoad.LoadConfig().GetInt64("performance.node.stageTimeout")
|
|
defaultTimeout := time.Duration(stageTimeout) * time.Second
|
|
select {
|
|
case <-s.execOver:
|
|
case <-time.After(defaultTimeout):
|
|
log.Printf("=====================")
|
|
//TODO #TEST BEGIN 测试时可以注释掉下面这行,否则调试时超时,会引发一个 panic,导致程序中断。
|
|
log.Panicf("stage[%s] ->[%s] 流程处理,超时[%v],请排查", stageName, deviceId, defaultTimeout)
|
|
}
|
|
}
|
|
func timeCost(nodeId, deviceId string, start time.Time) {
|
|
tc := time.Since(start)
|
|
log.Printf("stage[%s] ->[%s] 耗时 = %v", nodeId, deviceId, tc)
|
|
}
|
|
|