106 lines
3.5 KiB
Go
106 lines
3.5 KiB
Go
package event
|
||
|
||
import (
|
||
"database/sql"
|
||
"time"
|
||
|
||
"gitlink.org.cn/cloudream/common/pkgs/logger"
|
||
"gitlink.org.cn/cloudream/common/pkgs/mq"
|
||
"gitlink.org.cn/cloudream/storage/common/consts"
|
||
stgglb "gitlink.org.cn/cloudream/storage/common/globals"
|
||
agtmq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/agent"
|
||
scevt "gitlink.org.cn/cloudream/storage/common/pkgs/mq/scanner/event"
|
||
"gitlink.org.cn/cloudream/storage/scanner/internal/config"
|
||
)
|
||
|
||
// AgentCheckState 类封装了扫描器代理检查状态的事件。
|
||
type AgentCheckState struct {
|
||
*scevt.AgentCheckState
|
||
}
|
||
|
||
// NewAgentCheckState 创建一个新的AgentCheckState实例。
|
||
// evt: 传入的AgentCheckState实例。
|
||
// 返回: 新创建的AgentCheckState指针。
|
||
func NewAgentCheckState(evt *scevt.AgentCheckState) *AgentCheckState {
|
||
return &AgentCheckState{
|
||
AgentCheckState: evt,
|
||
}
|
||
}
|
||
|
||
// TryMerge 尝试合并当前事件与另一个事件。
|
||
// other: 待合并的另一个事件。
|
||
// 返回: 成功合并返回true,否则返回false。
|
||
func (t *AgentCheckState) TryMerge(other Event) bool {
|
||
event, ok := other.(*AgentCheckState)
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
return t.NodeID == event.NodeID
|
||
}
|
||
|
||
// Execute 执行节点状态检查操作。
|
||
// execCtx: 执行上下文,包含执行时所需的所有参数和环境。
|
||
func (t *AgentCheckState) Execute(execCtx ExecuteContext) {
|
||
log := logger.WithType[AgentCheckState]("Event")
|
||
log.Debugf("begin with %v", logger.FormatStruct(t.AgentCheckState))
|
||
defer log.Debugf("end")
|
||
|
||
// 尝试根据节点ID获取节点信息
|
||
node, err := execCtx.Args.DB.Node().GetByID(execCtx.Args.DB.SQLCtx(), t.NodeID)
|
||
if err == sql.ErrNoRows {
|
||
return
|
||
}
|
||
|
||
// 获取节点失败的处理
|
||
if err != nil {
|
||
log.WithField("NodeID", t.NodeID).Warnf("get node by id failed, err: %s", err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取代理客户端
|
||
agtCli, err := stgglb.AgentMQPool.Acquire(t.NodeID)
|
||
if err != nil {
|
||
log.WithField("NodeID", t.NodeID).Warnf("create agent client failed, err: %s", err.Error())
|
||
return
|
||
}
|
||
defer stgglb.AgentMQPool.Release(agtCli)
|
||
|
||
// 向代理请求获取当前状态
|
||
getResp, err := agtCli.GetState(agtmq.NewGetState(), mq.RequestOption{Timeout: time.Second * 30})
|
||
if err != nil {
|
||
log.WithField("NodeID", t.NodeID).Warnf("getting state: %s", err.Error())
|
||
|
||
// 检查节点上次上报时间,若超时则设置节点为不可用状态
|
||
if node.LastReportTime != nil && time.Since(*node.LastReportTime) > time.Duration(config.Cfg().NodeUnavailableSeconds)*time.Second {
|
||
err := execCtx.Args.DB.Node().UpdateState(execCtx.Args.DB.SQLCtx(), t.NodeID, consts.NodeStateUnavailable)
|
||
if err != nil {
|
||
log.WithField("NodeID", t.NodeID).Warnf("set node state failed, err: %s", err.Error())
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// 根据代理返回的节点状态更新节点状态
|
||
if getResp.IPFSState != consts.IPFSStateOK {
|
||
log.WithField("NodeID", t.NodeID).Warnf("IPFS status is %s, set node state unavailable", getResp.IPFSState)
|
||
|
||
err := execCtx.Args.DB.Node().UpdateState(execCtx.Args.DB.SQLCtx(), t.NodeID, consts.NodeStateUnavailable)
|
||
if err != nil {
|
||
log.WithField("NodeID", t.NodeID).Warnf("change node state failed, err: %s", err.Error())
|
||
}
|
||
return
|
||
}
|
||
|
||
// 更新节点状态为正常
|
||
err = execCtx.Args.DB.Node().UpdateState(execCtx.Args.DB.SQLCtx(), t.NodeID, consts.NodeStateNormal)
|
||
if err != nil {
|
||
log.WithField("NodeID", t.NodeID).Warnf("change node state failed, err: %s", err.Error())
|
||
}
|
||
}
|
||
|
||
// init 注册AgentCheckState消息转换器。
|
||
func init() {
|
||
RegisterMessageConvertor(NewAgentCheckState)
|
||
}
|