116 lines
2.7 KiB
Go
116 lines
2.7 KiB
Go
package ticktock
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"gitlink.org.cn/cloudream/common/pkgs/logger"
|
|
"gitlink.org.cn/cloudream/common/utils/reflect2"
|
|
"gitlink.org.cn/cloudream/jcs-pub/client/internal/db"
|
|
jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
|
|
|
|
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/publock/reqbuilder"
|
|
)
|
|
|
|
type UserSpaceGC struct {
|
|
}
|
|
|
|
func (j *UserSpaceGC) Name() string {
|
|
return reflect2.TypeNameOf[UserSpaceGC]()
|
|
}
|
|
|
|
// Execute 执行垃圾回收操作。
|
|
func (j *UserSpaceGC) Execute(t *TickTock) {
|
|
log := logger.WithType[UserSpaceGC]("Event")
|
|
startTime := time.Now()
|
|
log.Infof("job start")
|
|
defer func() {
|
|
log.Infof("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
|
|
}
|
|
|
|
j.gcOne(t, detail)
|
|
}
|
|
}
|
|
|
|
func (j *UserSpaceGC) gcOne(t *TickTock, space *jcstypes.UserSpaceDetail) {
|
|
log := logger.WithType[UserSpaceGC]("Event")
|
|
|
|
mutex, err := reqbuilder.NewBuilder().UserSpace().GC(space.UserSpace.UserSpaceID).MutexLock(t.pubLock)
|
|
if err != nil {
|
|
log.Warnf("acquire lock: %v", err)
|
|
return
|
|
}
|
|
defer mutex.Unlock()
|
|
|
|
if err := j.gcShards(t, space); err != nil {
|
|
log.Warnf("gc shard store of %v: %v", space.UserSpace.UserSpaceID, err)
|
|
}
|
|
|
|
if err := j.gcTemps(t, space); err != nil {
|
|
log.Warnf("gc base store of %v: %v", space.UserSpace.UserSpaceID, err)
|
|
}
|
|
}
|
|
|
|
func (j *UserSpaceGC) gcShards(t *TickTock, space *jcstypes.UserSpaceDetail) error {
|
|
db2 := t.db
|
|
|
|
// 收集需要进行垃圾回收的文件哈希值
|
|
var allFileHashes []jcstypes.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
|
|
}
|
|
|
|
store, err := t.stgPool.GetShardStore(space)
|
|
if err != nil {
|
|
return fmt.Errorf("getting shard store: %w", err)
|
|
}
|
|
|
|
err = store.GC(allFileHashes)
|
|
if err != nil {
|
|
return fmt.Errorf("gc shard store: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (j *UserSpaceGC) gcTemps(t *TickTock, space *jcstypes.UserSpaceDetail) error {
|
|
store, err := t.stgPool.GetBaseStore(space)
|
|
if err != nil {
|
|
return fmt.Errorf("getting base store: %w", err)
|
|
}
|
|
|
|
store.CleanTemps()
|
|
return nil
|
|
}
|