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.

check_cache.go 5.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package event
  2. import (
  3. "time"
  4. shell "github.com/ipfs/go-ipfs-api"
  5. "github.com/samber/lo"
  6. "gitlink.org.cn/cloudream/agent/internal/config"
  7. "gitlink.org.cn/cloudream/common/consts"
  8. evcst "gitlink.org.cn/cloudream/common/consts/event"
  9. "gitlink.org.cn/cloudream/common/pkg/logger"
  10. "gitlink.org.cn/cloudream/db/model"
  11. agtevt "gitlink.org.cn/cloudream/rabbitmq/message/agent/event"
  12. scmsg "gitlink.org.cn/cloudream/rabbitmq/message/scanner"
  13. scevt "gitlink.org.cn/cloudream/rabbitmq/message/scanner/event"
  14. )
  15. type CheckCache struct {
  16. agtevt.CheckCache
  17. }
  18. func NewCheckCache(isComplete bool, caches []model.Cache) *CheckCache {
  19. return &CheckCache{
  20. CheckCache: agtevt.NewCheckCache(isComplete, caches),
  21. }
  22. }
  23. func (t *CheckCache) TryMerge(other Event) bool {
  24. event, ok := other.(*CheckCache)
  25. if !ok {
  26. return false
  27. }
  28. if event.IsComplete {
  29. t.IsComplete = true
  30. t.Caches = event.Caches
  31. return true
  32. }
  33. if !t.IsComplete {
  34. t.Caches = append(t.Caches, event.Caches...)
  35. t.Caches = lo.UniqBy(t.Caches, func(ch model.Cache) string { return ch.FileHash })
  36. return true
  37. }
  38. return false
  39. }
  40. func (t *CheckCache) Execute(execCtx ExecuteContext) {
  41. log := logger.WithType[CheckCache]("Event")
  42. log.Debugf("begin with %v", logger.FormatStruct(t))
  43. filesMap, err := execCtx.Args.IPFS.GetPinnedFiles()
  44. if err != nil {
  45. log.Warnf("get pinned files from ipfs failed, err: %s", err.Error())
  46. return
  47. }
  48. // TODO 根据锁定清单过滤被锁定的文件的记录
  49. if t.IsComplete {
  50. t.checkComplete(filesMap, execCtx)
  51. } else {
  52. t.checkIncrement(filesMap, execCtx)
  53. }
  54. }
  55. func (t *CheckCache) checkIncrement(filesMap map[string]shell.PinInfo, execCtx ExecuteContext) {
  56. log := logger.WithType[CheckCache]("Event")
  57. var updateCacheOps []scevt.UpdateCacheEntry
  58. for _, cache := range t.Caches {
  59. _, ok := filesMap[cache.FileHash]
  60. if ok {
  61. if cache.State == consts.CACHE_STATE_PINNED {
  62. // 不处理
  63. } else if cache.State == consts.CACHE_STATE_TEMP {
  64. err := execCtx.Args.IPFS.Unpin(cache.FileHash)
  65. if err != nil {
  66. log.WithField("FileHash", cache.FileHash).Warnf("unpin file failed, err: %s", err.Error())
  67. }
  68. }
  69. // 删除map中的记录,表示此记录已被检查过
  70. delete(filesMap, cache.FileHash)
  71. } else {
  72. if cache.State == consts.CACHE_STATE_PINNED {
  73. // TODO 需要考虑此处是否是同步的过程
  74. err := execCtx.Args.IPFS.Pin(cache.FileHash)
  75. if err != nil {
  76. log.WithField("FileHash", cache.FileHash).Warnf("pin file failed, err: %s", err.Error())
  77. }
  78. } else if cache.State == consts.CACHE_STATE_TEMP {
  79. if time.Since(cache.CacheTime) > time.Duration(config.Cfg().TempFileLifetime)*time.Second {
  80. updateCacheOps = append(updateCacheOps, scevt.NewUpdateCacheEntry(cache.FileHash, evcst.UPDATE_CACHE_DELETE_TEMP))
  81. }
  82. }
  83. }
  84. }
  85. // 增量情况下,不需要对filesMap中没检查的记录进行处理
  86. if len(updateCacheOps) > 0 {
  87. evtmsg, err := scmsg.NewPostEventBody(
  88. scevt.NewUpdateCache(config.Cfg().ID, updateCacheOps),
  89. execCtx.Option.IsEmergency,
  90. execCtx.Option.DontMerge,
  91. )
  92. if err == nil {
  93. execCtx.Args.Scanner.PostEvent(evtmsg)
  94. } else {
  95. log.Warnf("new post event body failed, err: %s", err.Error())
  96. }
  97. }
  98. }
  99. func (t *CheckCache) checkComplete(filesMap map[string]shell.PinInfo, execCtx ExecuteContext) {
  100. log := logger.WithType[CheckCache]("Event")
  101. var updateCacheOps []scevt.UpdateCacheEntry
  102. for _, cache := range t.Caches {
  103. _, ok := filesMap[cache.FileHash]
  104. if ok {
  105. if cache.State == consts.CACHE_STATE_PINNED {
  106. // 不处理
  107. } else if cache.State == consts.CACHE_STATE_TEMP {
  108. err := execCtx.Args.IPFS.Unpin(cache.FileHash)
  109. if err != nil {
  110. log.WithField("FileHash", cache.FileHash).Warnf("unpin file failed, err: %s", err.Error())
  111. }
  112. }
  113. // 删除map中的记录,表示此记录已被检查过
  114. delete(filesMap, cache.FileHash)
  115. } else {
  116. if cache.State == consts.CACHE_STATE_PINNED {
  117. // TODO 需要考虑此处是否是同步的过程
  118. err := execCtx.Args.IPFS.Pin(cache.FileHash)
  119. if err != nil {
  120. log.WithField("FileHash", cache.FileHash).Warnf("pin file failed, err: %s", err.Error())
  121. }
  122. } else if cache.State == consts.CACHE_STATE_TEMP {
  123. if time.Since(cache.CacheTime) > time.Duration(config.Cfg().TempFileLifetime)*time.Second {
  124. updateCacheOps = append(updateCacheOps, scevt.NewUpdateCacheEntry(cache.FileHash, evcst.UPDATE_CACHE_DELETE_TEMP))
  125. }
  126. }
  127. }
  128. }
  129. // map中剩下的数据是没有被遍历过,即Cache中没有记录的
  130. for hash, _ := range filesMap {
  131. updateCacheOps = append(updateCacheOps, scevt.NewUpdateCacheEntry(hash, evcst.UPDATE_CACHE_CREATE_TEMP))
  132. }
  133. evtmsg, err := scmsg.NewPostEventBody(
  134. scevt.NewUpdateCache(config.Cfg().ID, updateCacheOps),
  135. execCtx.Option.IsEmergency,
  136. execCtx.Option.DontMerge,
  137. )
  138. if err == nil {
  139. execCtx.Args.Scanner.PostEvent(evtmsg)
  140. } else {
  141. log.Warnf("new post event body failed, err: %s", err.Error())
  142. }
  143. }
  144. func init() {
  145. Register(func(val agtevt.CheckCache) Event { return NewCheckCache(val.IsComplete, val.Caches) })
  146. }

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