You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

user_space_gc.go 2.8 kB

6 months ago
6 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package ticktock
  2. import (
  3. "fmt"
  4. "time"
  5. "gitlink.org.cn/cloudream/common/pkgs/logger"
  6. "gitlink.org.cn/cloudream/common/utils/reflect2"
  7. "gitlink.org.cn/cloudream/jcs-pub/client/internal/db"
  8. jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
  9. )
  10. type UserSpaceGC struct {
  11. }
  12. func (j *UserSpaceGC) Name() string {
  13. return reflect2.TypeNameOf[UserSpaceGC]()
  14. }
  15. // Execute 执行垃圾回收操作。
  16. func (j *UserSpaceGC) Execute(t *TickTock) {
  17. log := logger.WithType[UserSpaceGC]("Event")
  18. startTime := time.Now()
  19. log.Infof("job start")
  20. defer func() {
  21. log.Infof("job end, time: %v", time.Since(startTime))
  22. }()
  23. if !t.cluster.IsMaster() {
  24. log.Infof("not master, skip")
  25. return
  26. }
  27. spaceIDs, err := t.db.UserSpace().GetAllIDs(t.db.DefCtx())
  28. if err != nil {
  29. log.Warnf("getting user space ids: %v", err)
  30. return
  31. }
  32. for _, spaceID := range spaceIDs {
  33. detail := t.spaceMeta.Get(spaceID)
  34. if detail == nil {
  35. continue
  36. }
  37. j.gcOne(t, detail)
  38. }
  39. }
  40. func (j *UserSpaceGC) gcOne(t *TickTock, space *jcstypes.UserSpaceDetail) {
  41. log := logger.WithType[UserSpaceGC]("Event")
  42. mutex, err := t.pubLock.BeginMutex().UserSpace().GC(space.UserSpace.UserSpaceID).End().Lock()
  43. if err != nil {
  44. log.Warnf("acquire lock: %v", err)
  45. return
  46. }
  47. defer mutex.Unlock()
  48. if err := j.gcShards(t, space); err != nil {
  49. log.Warnf("gc shard store of %v: %v", space.UserSpace.UserSpaceID, err)
  50. }
  51. if err := j.gcTemps(t, space); err != nil {
  52. log.Warnf("gc base store of %v: %v", space.UserSpace.UserSpaceID, err)
  53. }
  54. }
  55. func (j *UserSpaceGC) gcShards(t *TickTock, space *jcstypes.UserSpaceDetail) error {
  56. db2 := t.db
  57. // 收集需要进行垃圾回收的文件哈希值
  58. var allFileHashes []jcstypes.FileHash
  59. err := db2.DoTx(func(tx db.SQLContext) error {
  60. blocks, err := db2.ObjectBlock().GetByUserSpaceID(tx, space.UserSpace.UserSpaceID)
  61. if err != nil {
  62. return fmt.Errorf("getting object blocks by hub id: %w", err)
  63. }
  64. for _, c := range blocks {
  65. allFileHashes = append(allFileHashes, c.FileHash)
  66. }
  67. objs, err := db2.PinnedObject().GetObjectsByUserSpaceID(tx, space.UserSpace.UserSpaceID)
  68. if err != nil {
  69. return fmt.Errorf("getting pinned objects by hub id: %w", err)
  70. }
  71. for _, o := range objs {
  72. allFileHashes = append(allFileHashes, o.FileHash)
  73. }
  74. return nil
  75. })
  76. if err != nil {
  77. return err
  78. }
  79. store, err := t.stgPool.GetShardStore(space)
  80. if err != nil {
  81. return fmt.Errorf("getting shard store: %w", err)
  82. }
  83. err = store.GC(allFileHashes)
  84. if err != nil {
  85. return fmt.Errorf("gc shard store: %w", err)
  86. }
  87. return nil
  88. }
  89. func (j *UserSpaceGC) gcTemps(t *TickTock, space *jcstypes.UserSpaceDetail) error {
  90. store, err := t.stgPool.GetBaseStore(space)
  91. if err != nil {
  92. return fmt.Errorf("getting base store: %w", err)
  93. }
  94. store.CleanTemps()
  95. return nil
  96. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。