package ticktock import ( "fmt" "time" "gitlink.org.cn/cloudream/common/pkgs/logger" "gitlink.org.cn/cloudream/common/pkgs/mq" "gitlink.org.cn/cloudream/common/utils/reflect2" "gitlink.org.cn/cloudream/jcs-pub/client/internal/db" "gitlink.org.cn/cloudream/jcs-pub/client/types" stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/distlock/reqbuilder" hubmq "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/mq/hub" ) type ShardStoreGC struct { } func (j *ShardStoreGC) Name() string { return reflect2.TypeNameOf[ShardStoreGC]() } // Execute 执行垃圾回收操作。 func (j *ShardStoreGC) Execute(t *TickTock) { log := logger.WithType[ShardStoreGC]("Event") startTime := time.Now() log.Debugf("job start") defer func() { log.Debugf("job end, time: %v", time.Since(startTime)) }() spaceIDs, err := t.db.UserSpace().GetAllIDs(t.db.DefCtx()) if err != nil { log.Warnf("getting user space ids: %v", err) return } for _, spaceID := range spaceIDs { detail := t.spaceMeta.Get(spaceID) if detail == nil { continue } err := j.gcOne(t, detail) if err != nil { log.Warnf("gc one user space: %v: %v", spaceID, err) continue } } } func (j *ShardStoreGC) gcOne(t *TickTock, space *types.UserSpaceDetail) error { mutex, err := reqbuilder.NewBuilder().Shard().GC(space.UserSpace.UserSpaceID).MutexLock(t.pubLock) if err != nil { return fmt.Errorf("acquire lock: %w", err) } defer mutex.Unlock() db2 := t.db // 收集需要进行垃圾回收的文件哈希值 var allFileHashes []types.FileHash err = db2.DoTx(func(tx db.SQLContext) error { blocks, err := db2.ObjectBlock().GetByUserSpaceID(tx, space.UserSpace.UserSpaceID) 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 := db2.PinnedObject().GetObjectsByUserSpaceID(tx, space.UserSpace.UserSpaceID) 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 { return err } // 获取与节点通信的代理客户端 agtCli, err := stgglb.HubMQPool.Acquire(space.MasterHub.HubID) if err != nil { return fmt.Errorf("new hub mq client: %w", err) } defer stgglb.HubMQPool.Release(agtCli) // 向代理发送垃圾回收请求 _, err = agtCli.CacheGC(hubmq.ReqCacheGC(*space, allFileHashes), mq.RequestOption{Timeout: time.Minute}) if err != nil { return fmt.Errorf("request to cache gc: %w", err) } return nil }