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.

ipfs.go 4.3 kB

2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package mq
  2. import (
  3. "time"
  4. shell "github.com/ipfs/go-ipfs-api"
  5. "gitlink.org.cn/cloudream/common/consts/errorcode"
  6. "gitlink.org.cn/cloudream/common/pkgs/ipfs"
  7. "gitlink.org.cn/cloudream/common/pkgs/logger"
  8. "gitlink.org.cn/cloudream/common/pkgs/mq"
  9. "gitlink.org.cn/cloudream/storage-agent/internal/config"
  10. "gitlink.org.cn/cloudream/storage-agent/internal/task"
  11. "gitlink.org.cn/cloudream/storage-common/consts"
  12. "gitlink.org.cn/cloudream/storage-common/globals"
  13. agtmq "gitlink.org.cn/cloudream/storage-common/pkgs/mq/agent"
  14. )
  15. func (svc *Service) CheckIPFS(msg *agtmq.CheckIPFS) (*agtmq.CheckIPFSResp, *mq.CodeMessage) {
  16. ipfsCli, err := globals.IPFSPool.Acquire()
  17. if err != nil {
  18. logger.Warnf("new ipfs client: %s", err.Error())
  19. return mq.ReplyFailed[agtmq.CheckIPFSResp](errorcode.OperationFailed, "new ipfs client failed")
  20. }
  21. defer ipfsCli.Close()
  22. filesMap, err := ipfsCli.GetPinnedFiles()
  23. if err != nil {
  24. logger.Warnf("get pinned files from ipfs failed, err: %s", err.Error())
  25. return mq.ReplyFailed[agtmq.CheckIPFSResp](errorcode.OperationFailed, "get pinned files from ipfs failed")
  26. }
  27. // TODO 根据锁定清单过滤被锁定的文件的记录
  28. if msg.IsComplete {
  29. return svc.checkComplete(msg, filesMap, ipfsCli)
  30. } else {
  31. return svc.checkIncrement(msg, filesMap, ipfsCli)
  32. }
  33. }
  34. func (svc *Service) checkIncrement(msg *agtmq.CheckIPFS, filesMap map[string]shell.PinInfo, ipfsCli *ipfs.PoolClient) (*agtmq.CheckIPFSResp, *mq.CodeMessage) {
  35. var entries []agtmq.CheckIPFSRespEntry
  36. for _, cache := range msg.Caches {
  37. _, ok := filesMap[cache.FileHash]
  38. if ok {
  39. if cache.State == consts.CacheStatePinned {
  40. // 不处理
  41. } else if cache.State == consts.CacheStateTemp {
  42. logger.WithField("FileHash", cache.FileHash).Debugf("unpin for cache entry state is temp")
  43. err := ipfsCli.Unpin(cache.FileHash)
  44. if err != nil {
  45. logger.WithField("FileHash", cache.FileHash).Warnf("unpin file failed, err: %s", err.Error())
  46. }
  47. }
  48. // 删除map中的记录,表示此记录已被检查过
  49. delete(filesMap, cache.FileHash)
  50. } else {
  51. if cache.State == consts.CacheStatePinned {
  52. svc.taskManager.StartComparable(task.NewIPFSPin(cache.FileHash))
  53. } else if cache.State == consts.CacheStateTemp {
  54. if time.Since(cache.CacheTime) > time.Duration(config.Cfg().TempFileLifetime)*time.Second {
  55. entries = append(entries, agtmq.NewCheckIPFSRespEntry(cache.FileHash, agtmq.CHECK_IPFS_RESP_OP_DELETE_TEMP))
  56. }
  57. }
  58. }
  59. }
  60. // 增量情况下,不需要对filesMap中没检查的记录进行处理
  61. return mq.ReplyOK(agtmq.NewCheckIPFSResp(entries))
  62. }
  63. func (svc *Service) checkComplete(msg *agtmq.CheckIPFS, filesMap map[string]shell.PinInfo, ipfsCli *ipfs.PoolClient) (*agtmq.CheckIPFSResp, *mq.CodeMessage) {
  64. var entries []agtmq.CheckIPFSRespEntry
  65. for _, cache := range msg.Caches {
  66. _, ok := filesMap[cache.FileHash]
  67. if ok {
  68. if cache.State == consts.CacheStatePinned {
  69. // 不处理
  70. } else if cache.State == consts.CacheStateTemp {
  71. logger.WithField("FileHash", cache.FileHash).Debugf("unpin for cache entry state is temp")
  72. err := ipfsCli.Unpin(cache.FileHash)
  73. if err != nil {
  74. logger.WithField("FileHash", cache.FileHash).Warnf("unpin file failed, err: %s", err.Error())
  75. }
  76. }
  77. // 删除map中的记录,表示此记录已被检查过
  78. delete(filesMap, cache.FileHash)
  79. } else {
  80. if cache.State == consts.CacheStatePinned {
  81. svc.taskManager.StartComparable(task.NewIPFSPin(cache.FileHash))
  82. } else if cache.State == consts.CacheStateTemp {
  83. if time.Since(cache.CacheTime) > time.Duration(config.Cfg().TempFileLifetime)*time.Second {
  84. entries = append(entries, agtmq.NewCheckIPFSRespEntry(cache.FileHash, agtmq.CHECK_IPFS_RESP_OP_DELETE_TEMP))
  85. }
  86. }
  87. }
  88. }
  89. // map中剩下的数据是没有被遍历过,即Cache中没有记录的,那么就Unpin文件,并产生一条Temp记录
  90. for hash := range filesMap {
  91. logger.WithField("FileHash", hash).Debugf("unpin for no cacah entry")
  92. err := ipfsCli.Unpin(hash)
  93. if err != nil {
  94. logger.WithField("FileHash", hash).Warnf("unpin file failed, err: %s", err.Error())
  95. }
  96. entries = append(entries, agtmq.NewCheckIPFSRespEntry(hash, agtmq.CHECK_IPFS_RESP_OP_CREATE_TEMP))
  97. }
  98. return mq.ReplyOK(agtmq.NewCheckIPFSResp(entries))
  99. }

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