114 lines
3.1 KiB
Go
114 lines
3.1 KiB
Go
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)
|
||
}
|