|
- package ticktock
-
- import (
- "fmt"
- "time"
-
- "github.com/samber/lo"
- "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"
- clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
- stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals"
- hubmq "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/mq/hub"
- )
-
- // CheckShardStore 代表一个用于处理代理缓存检查事件的结构体
- type CheckShardStore struct {
- }
-
- func (j *CheckShardStore) Name() string {
- return reflect2.TypeNameOf[CheckShardStore]()
- }
-
- // Execute 执行缓存检查操作,对比本地缓存与代理返回的缓存信息,更新数据库中的缓存记录
- func (j *CheckShardStore) Execute(t *TickTock) {
- log := logger.WithType[CheckShardStore]("TickTock")
- startTime := time.Now()
- log.Debugf("job start")
- defer func() {
- log.Debugf("job end, time: %v", time.Since(startTime))
- }()
-
- db2 := t.db
-
- spaceIDs, err := db2.UserSpace().GetAllIDs(db2.DefCtx())
- if err != nil {
- log.Warnf("getting all user space ids: %s", err.Error())
- return
- }
-
- for _, spaceID := range spaceIDs {
- detail := t.spaceMeta.Get(spaceID)
- if detail == nil {
- continue
- }
-
- err := j.checkOne(t, detail)
- if err != nil {
- log.Warnf("checking user space %v: %v", detail.String(), err)
- continue
- }
- }
- }
-
- func (j *CheckShardStore) checkOne(t *TickTock, space *clitypes.UserSpaceDetail) error {
- log := logger.WithType[CheckShardStore]("TickTock")
-
- if space.MasterHub == nil {
- log.Infof("user space %v has no master hub", space.UserSpace)
- return nil
- }
-
- 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)
-
- checkResp, err := agtCli.CheckCache(hubmq.NewCheckCache(*space), mq.RequestOption{Timeout: time.Minute})
- if err != nil {
- return fmt.Errorf("request to check cache: %w", err)
- }
-
- realFileHashes := lo.SliceToMap(checkResp.FileHashes, func(hash clitypes.FileHash) (clitypes.FileHash, bool) { return hash, true })
-
- // 在事务中执行缓存更新操作
- t.db.DoTx(func(tx db.SQLContext) error {
- j.checkPinnedObject(t, tx, space, realFileHashes)
-
- j.checkObjectBlock(t, tx, space, realFileHashes)
- return nil
- })
- return nil
- }
-
- // checkPinnedObject 对比PinnedObject表,若实际文件不存在,则进行删除操作
- func (*CheckShardStore) checkPinnedObject(t *TickTock, tx db.SQLContext, space *clitypes.UserSpaceDetail, realFileHashes map[clitypes.FileHash]bool) {
- log := logger.WithType[CheckShardStore]("TickTock")
-
- objs, err := t.db.PinnedObject().GetObjectsByUserSpaceID(tx, space.UserSpace.UserSpaceID)
- if err != nil {
- log.Warnf("getting pinned objects by user space id %v: %v", space.UserSpace, err)
- return
- }
-
- var rms []clitypes.ObjectID
- for _, c := range objs {
- if realFileHashes[c.FileHash] {
- continue
- }
- rms = append(rms, c.ObjectID)
- }
-
- if len(rms) > 0 {
- err = t.db.PinnedObject().BatchDelete(tx, space.UserSpace.UserSpaceID, rms)
- if err != nil {
- log.Warnf("batch delete user space %v pinned objects: %v", space.UserSpace, err)
- }
- }
- }
-
- // checkObjectBlock 对比ObjectBlock表,若实际文件不存在,则进行删除操作
- func (*CheckShardStore) checkObjectBlock(t *TickTock, tx db.SQLContext, space *clitypes.UserSpaceDetail, realFileHashes map[clitypes.FileHash]bool) {
- log := logger.WithType[CheckShardStore]("TickTock")
-
- blocks, err := t.db.ObjectBlock().GetByUserSpaceID(tx, space.UserSpace.UserSpaceID)
- if err != nil {
- log.Warnf("getting object blocks by user space id %v: %v", space.UserSpace, err)
- return
- }
-
- var rms []clitypes.FileHash
- for _, b := range blocks {
- if realFileHashes[b.FileHash] {
- continue
- }
- rms = append(rms, b.FileHash)
- }
-
- if len(rms) > 0 {
- err = t.db.ObjectBlock().BatchDeleteByFileHash(tx, space.UserSpace.UserSpaceID, rms)
- if err != nil {
- log.Warnf("batch delete user space %v object blocks: %v", space.UserSpace, err)
- }
- }
- }
|