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.

blockdistribution.go 6.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package models
  2. import (
  3. "errors"
  4. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  5. stgmod "gitlink.org.cn/cloudream/storage/common/models"
  6. "gorm.io/gorm"
  7. "log"
  8. "strconv"
  9. "time"
  10. )
  11. type BlockDistribution struct {
  12. BlockID int64 `gorm:"column:BlockID; primaryKey; type:bigint; autoIncrement" json:"blockID"`
  13. ObjectID int64 `gorm:"column:ObjectID; type:bigint; not null" json:"objectID"`
  14. Type string `gorm:"column:Type; type:varchar(1024); not null" json:"type"`
  15. Index int64 `gorm:"column:Index; type:bigint; not null" json:"index"`
  16. StorageID int64 `gorm:"column:StorageID; type:bigint; not null" json:"storageID"`
  17. Status int `gorm:"column:Status; type:tinyint; not null" json:"status"`
  18. Timestamp time.Time `gorm:"column:Timestamp; type:datatime; not null" json:"timestamp"`
  19. }
  20. func (BlockDistribution) TableName() string {
  21. return "blockdistribution"
  22. }
  23. type BlockDistributionRepository struct {
  24. repo *GormRepository
  25. }
  26. func NewBlockDistributionRepository(db *gorm.DB) *BlockDistributionRepository {
  27. return &BlockDistributionRepository{repo: NewGormRepository(db)}
  28. }
  29. func (r *BlockDistributionRepository) CreateBlockDistribution(block *BlockDistribution) error {
  30. return r.repo.Create(block)
  31. }
  32. func (r *BlockDistributionRepository) UpdateBlockDistribution(block *BlockDistribution) error {
  33. return r.repo.Update(block)
  34. }
  35. func (r *BlockDistributionRepository) GetAllBlocks() ([]BlockDistribution, error) {
  36. var blocks []BlockDistribution
  37. err := r.repo.GetAll(&blocks)
  38. if err != nil {
  39. return nil, err
  40. }
  41. return blocks, nil
  42. }
  43. func (r *BlockDistributionRepository) GetBlockDistributionByObjectID(objectID int64) ([]BlockDistribution, error) {
  44. var blocks []BlockDistribution
  45. query := "SELECT * FROM blockdistribution WHERE ObjectID = ?"
  46. err := r.repo.db.Raw(query, objectID).Scan(&blocks).Error
  47. if errors.Is(err, gorm.ErrRecordNotFound) {
  48. return []BlockDistribution{}, errors.New("block not found")
  49. }
  50. return blocks, nil
  51. }
  52. func (r *BlockDistributionRepository) GetStorageIDsByObjectID(objectID int64) ([]int64, error) {
  53. var storageIDs []int64
  54. query := "SELECT distinct storageID FROM blockdistribution WHERE ObjectID = ?"
  55. // 通过 ObjectID 查询
  56. err := r.repo.db.Raw(query, objectID).Scan(&storageIDs).Error
  57. if errors.Is(err, gorm.ErrRecordNotFound) {
  58. return []int64{}, errors.New("block not found")
  59. }
  60. return storageIDs, nil
  61. }
  62. func (r *BlockDistributionRepository) GetBlockDistributionByIndex(objectID int64, index int64, storageID int64) (BlockDistribution, error) {
  63. var block BlockDistribution
  64. query := "SELECT * FROM blockdistribution WHERE ObjectID = ? AND `Index` = ? AND StorageID = ?"
  65. // 通过 ObjectID 和 Index 联合查询
  66. err := r.repo.db.Exec(query, objectID, index, storageID).First(&block).Error
  67. if errors.Is(err, gorm.ErrRecordNotFound) {
  68. return BlockDistribution{}, errors.New("block not found")
  69. }
  70. return block, nil
  71. }
  72. // DeleteBlockDistribution 删除 BlockDistribution 记录 (根据 ObjectID 和 Index)
  73. func (r *BlockDistributionRepository) DeleteBlockDistribution(objectID int64, index int64, storageID int64) error {
  74. query := "DELETE FROM blockdistribution WHERE ObjectID = ? AND `Index` = ? AND StorageID = ?"
  75. return r.repo.db.Exec(query, objectID, index, storageID).Error
  76. }
  77. // ProcessBlockDistribution mq推送各节点统计自身当前的总数据量时的处理逻辑
  78. func ProcessBlockDistribution(data stgmod.BlockDistribution) {
  79. repoObject := NewObjectRepository(DB)
  80. repoBlock := NewBlockDistributionRepository(DB)
  81. repoStorage := NewStorageTransferCountRepository(DB)
  82. //更新object表中的状态
  83. object, err := repoObject.GetObjectByID(data.Body.Object.ObjectID)
  84. faultTolerance, _ := strconv.ParseFloat(data.Body.Object.FaultTolerance, 64)
  85. redundancy, _ := strconv.ParseFloat(data.Body.Object.Redundancy, 64)
  86. avgAccessCost, _ := strconv.ParseFloat(data.Body.Object.AvgAccessCost, 64)
  87. if errors.Is(err, gorm.ErrRecordNotFound) {
  88. err := repoObject.CreateObject(&Object{
  89. ObjectID: cdssdk.ObjectID(data.Body.Object.ObjectID),
  90. PackageID: cdssdk.PackageID(data.Body.Object.PackageID),
  91. Path: data.Body.Object.Path,
  92. Size: data.Body.Object.Size,
  93. FileHash: data.Body.Object.FileHash,
  94. Status: StatusYesterdayAfter,
  95. FaultTolerance: faultTolerance,
  96. Redundancy: redundancy,
  97. AvgAccessCost: avgAccessCost,
  98. Timestamp: time.Now(),
  99. })
  100. if err != nil {
  101. log.Printf("Error create object: %v", err)
  102. }
  103. } else {
  104. object.Status = StatusYesterdayAfter
  105. err = repoObject.UpdateObject(object)
  106. if err != nil {
  107. log.Printf("Error update object: %v", err)
  108. }
  109. }
  110. //更新block表中的状态
  111. for _, blockDistribution := range data.Body.Object.BlockDistribution {
  112. blockIndex, _ := strconv.ParseInt(blockDistribution.Index, 10, 64)
  113. blockStorageID, _ := strconv.ParseInt(blockDistribution.StorageID, 10, 64)
  114. blockDist, err := repoBlock.GetBlockDistributionByIndex(data.Body.Object.ObjectID, blockIndex, blockStorageID)
  115. if errors.Is(err, gorm.ErrRecordNotFound) {
  116. err := repoBlock.CreateBlockDistribution(&BlockDistribution{
  117. BlockID: blockDist.BlockID,
  118. ObjectID: blockDist.ObjectID,
  119. Type: blockDistribution.Type,
  120. Index: blockIndex,
  121. StorageID: blockStorageID,
  122. Status: StatusYesterdayAfter,
  123. Timestamp: time.Now(),
  124. })
  125. if err != nil {
  126. log.Printf("Error create BlockDistribution: %v", err)
  127. }
  128. } else {
  129. err := repoBlock.UpdateBlockDistribution(&BlockDistribution{
  130. BlockID: blockDist.BlockID,
  131. ObjectID: blockDist.ObjectID,
  132. Type: blockDistribution.Type,
  133. Index: blockIndex,
  134. StorageID: blockStorageID,
  135. Status: StatusYesterdayAfter,
  136. Timestamp: time.Now(),
  137. })
  138. if err != nil {
  139. log.Printf("Error update BlockDistribution: %v", err)
  140. }
  141. }
  142. }
  143. //在storageTransferCount表中添加记录
  144. for _, dataTransfer := range data.Body.Object.DataTransfers {
  145. sourceStorageID, _ := strconv.ParseInt(dataTransfer.SourceStorageID, 10, 64)
  146. targetStorageID, _ := strconv.ParseInt(dataTransfer.TargetStorageID, 10, 64)
  147. dataTransferCount, _ := strconv.ParseInt(dataTransfer.DataTransferCount, 10, 64)
  148. err := repoStorage.CreateStorageTransferCount(&StorageTransferCount{
  149. ObjectID: data.Body.Object.ObjectID,
  150. Status: StatusTodayBeforeYesterday,
  151. SourceStorageID: sourceStorageID,
  152. TargetStorageID: targetStorageID,
  153. DataTransferCount: dataTransferCount,
  154. Timestamp: time.Now(),
  155. })
  156. if err != nil {
  157. log.Printf("Error create StorageTransferCount : %v", err)
  158. }
  159. }
  160. }

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