JCS-pub/scanner/internal/event/agent_cache_gc.go

114 lines
3.1 KiB
Go
Raw 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 event
import (
"database/sql"
"fmt"
"time"
"github.com/jmoiron/sqlx"
"gitlink.org.cn/cloudream/common/pkgs/logger"
"gitlink.org.cn/cloudream/common/pkgs/mq"
stgglb "gitlink.org.cn/cloudream/storage/common/globals"
"gitlink.org.cn/cloudream/storage/common/pkgs/distlock/reqbuilder"
agtmq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/agent"
scevt "gitlink.org.cn/cloudream/storage/common/pkgs/mq/scanner/event"
)
// AgentCacheGC 类封装了扫描器事件中的AgentCacheGC结构。
type AgentCacheGC struct {
*scevt.AgentCacheGC
}
// NewAgentCacheGC 创建一个新的AgentCacheGC实例。
// evt: 传入的扫描器事件中的AgentCacheGC实例。
func NewAgentCacheGC(evt *scevt.AgentCacheGC) *AgentCacheGC {
return &AgentCacheGC{
AgentCacheGC: evt,
}
}
// TryMerge 尝试合并当前事件与另一个事件。
// other: 待合并的另一个事件。
// 返回值表示是否成功合并。
func (t *AgentCacheGC) TryMerge(other Event) bool {
event, ok := other.(*AgentCacheGC)
if !ok {
return false
}
if event.NodeID != t.NodeID {
return false
}
return true
}
// Execute 执行垃圾回收操作。
// execCtx: 执行上下文,包含执行所需的各种参数和环境。
func (t *AgentCacheGC) Execute(execCtx ExecuteContext) {
log := logger.WithType[AgentCacheGC]("Event")
startTime := time.Now()
log.Debugf("begin with %v", logger.FormatStruct(t.AgentCacheGC))
defer func() {
log.Debugf("end, time: %v", time.Since(startTime))
}()
// 使用分布式锁进行资源锁定
mutex, err := reqbuilder.NewBuilder().
// 执行IPFS垃圾回收
IPFS().GC(t.NodeID).
MutexLock(execCtx.Args.DistLock)
if err != nil {
log.Warnf("acquire locks failed, err: %s", err.Error())
return
}
defer mutex.Unlock()
// 收集需要进行垃圾回收的文件哈希值
var allFileHashes []string
err = execCtx.Args.DB.DoTx(sql.LevelSerializable, func(tx *sqlx.Tx) error {
blocks, err := execCtx.Args.DB.ObjectBlock().GetByNodeID(tx, t.NodeID)
if err != nil {
return fmt.Errorf("getting object blocks by node id: %w", err)
}
for _, c := range blocks {
allFileHashes = append(allFileHashes, c.FileHash)
}
objs, err := execCtx.Args.DB.PinnedObject().GetObjectsByNodeID(tx, t.NodeID)
if err != nil {
return fmt.Errorf("getting pinned objects by node id: %w", err)
}
for _, o := range objs {
allFileHashes = append(allFileHashes, o.FileHash)
}
return nil
})
if err != nil {
log.WithField("NodeID", t.NodeID).Warn(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)
// 向代理发送垃圾回收请求
_, err = agtCli.CacheGC(agtmq.ReqCacheGC(allFileHashes), mq.RequestOption{Timeout: time.Minute})
if err != nil {
log.WithField("NodeID", t.NodeID).Warnf("ipfs gc: %s", err.Error())
return
}
}
// 注册消息转换器使系统能够处理AgentCacheGC消息。
func init() {
RegisterMessageConvertor(NewAgentCacheGC)
}