package event import ( "fmt" "time" "gitlink.org.cn/cloudream/common/pkgs/logger" "gitlink.org.cn/cloudream/common/pkgs/mq" cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" stgglb "gitlink.org.cn/cloudream/storage2/common/globals" "gitlink.org.cn/cloudream/storage2/common/pkgs/db2" "gitlink.org.cn/cloudream/storage2/common/pkgs/distlock/reqbuilder" agtmq "gitlink.org.cn/cloudream/storage2/common/pkgs/mq/hub" scevt "gitlink.org.cn/cloudream/storage2/common/pkgs/mq/scanner/event" ) // HubShardStoreGC 类封装了扫描器事件中的HubShardStoreGC结构。 type HubShardStoreGC struct { *scevt.HubShardStoreGC } // NewHubShardStoreGC 创建一个新的HubCacheGC实例。 // evt: 传入的扫描器事件中的HubCacheGC实例。 func NewHubShardStoreGC(evt *scevt.HubShardStoreGC) *HubShardStoreGC { return &HubShardStoreGC{ HubShardStoreGC: evt, } } // TryMerge 尝试合并当前事件与另一个事件。 // other: 待合并的另一个事件。 // 返回值表示是否成功合并。 func (t *HubShardStoreGC) TryMerge(other Event) bool { event, ok := other.(*HubShardStoreGC) if !ok { return false } if event.StorageID != t.StorageID { return false } return true } // Execute 执行垃圾回收操作。 // execCtx: 执行上下文,包含执行所需的各种参数和环境。 func (t *HubShardStoreGC) Execute(execCtx ExecuteContext) { log := logger.WithType[HubShardStoreGC]("Event") startTime := time.Now() log.Debugf("begin with %v", logger.FormatStruct(t.HubShardStoreGC)) defer func() { log.Debugf("end, time: %v", time.Since(startTime)) }() // 使用分布式锁进行资源锁定 mutex, err := reqbuilder.NewBuilder(). // 执行IPFS垃圾回收 Shard().GC(t.StorageID). MutexLock(execCtx.Args.DistLock) if err != nil { log.Warnf("acquire locks failed, err: %s", err.Error()) return } defer mutex.Unlock() // 收集需要进行垃圾回收的文件哈希值 var allFileHashes []cdssdk.FileHash var masterHub cdssdk.Hub err = execCtx.Args.DB.DoTx(func(tx db2.SQLContext) error { stg, err := execCtx.Args.DB.Storage().GetByID(tx, t.StorageID) if err != nil { return fmt.Errorf("getting storage by id: %w", err) } masterHub, err = execCtx.Args.DB.Hub().GetByID(tx, stg.MasterHub) if err != nil { return fmt.Errorf("getting master hub by id: %w", err) } blocks, err := execCtx.Args.DB.ObjectBlock().GetByStorageID(tx, t.StorageID) if err != nil { return fmt.Errorf("getting object blocks by hub id: %w", err) } for _, c := range blocks { allFileHashes = append(allFileHashes, c.FileHash) } objs, err := execCtx.Args.DB.PinnedObject().GetObjectsByStorageID(tx, t.StorageID) if err != nil { return fmt.Errorf("getting pinned objects by hub id: %w", err) } for _, o := range objs { allFileHashes = append(allFileHashes, o.FileHash) } return nil }) if err != nil { log.WithField("HubID", t.StorageID).Warn(err.Error()) return } // 获取与节点通信的代理客户端 agtCli, err := stgglb.HubMQPool.Acquire(masterHub.HubID) if err != nil { log.WithField("HubID", t.StorageID).Warnf("create hub client failed, err: %s", err.Error()) return } defer stgglb.HubMQPool.Release(agtCli) // 向代理发送垃圾回收请求 _, err = agtCli.CacheGC(agtmq.ReqCacheGC(t.StorageID, allFileHashes), mq.RequestOption{Timeout: time.Minute}) if err != nil { log.WithField("HubID", t.StorageID).Warnf("ipfs gc: %s", err.Error()) return } } // 注册消息转换器,使系统能够处理HubCacheGC消息。 func init() { RegisterMessageConvertor(NewHubShardStoreGC) }