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.

blocktransfer.go 9.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package models
  2. import (
  3. "errors"
  4. "fmt"
  5. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  6. stgmod "gitlink.org.cn/cloudream/storage/common/models"
  7. "gitlink.org.cn/cloudream/storage/common/pkgs/sysevent"
  8. "gorm.io/gorm"
  9. "log"
  10. "strconv"
  11. "time"
  12. )
  13. type StorageTransferCount struct {
  14. RelationshipID int64 `gorm:"column:RelationshipID; primaryKey; type:bigint; autoIncrement" json:"relationshipID"`
  15. ObjectID int64 `gorm:"column:ObjectID; type:bigint; not null" json:"objectID"`
  16. Status int64 `gorm:"column:Status; type:bigint; not null" json:"status"` // 连线左侧的状态
  17. SourceStorageID int64 `gorm:"column:SourceStorageID; type:bigint; not null" json:"sourceStorageID"` // 源存储节点 ID
  18. TargetStorageID int64 `gorm:"column:TargetStorageID; type:bigint; not null" json:"targetStorageID"` // 目标存储节点 ID
  19. DataTransferCount int64 `gorm:"column:DataTransferCount; type:bigint; not null" json:"dataTransferCount"` // 数据传输量
  20. Timestamp time.Time `gorm:"column:Timestamp; type:datatime; not null" json:"timestamp"` // 变化结束时间戳
  21. }
  22. func (StorageTransferCount) TableName() string {
  23. return "storagetransfercount"
  24. }
  25. type StorageTransferCountRepository struct {
  26. repo *GormRepository
  27. }
  28. func NewStorageTransferCountRepository(db *gorm.DB) *StorageTransferCountRepository {
  29. return &StorageTransferCountRepository{repo: NewGormRepository(db)}
  30. }
  31. func (r *StorageTransferCountRepository) CreateStorageTransferCount(storageTransferCount *StorageTransferCount) error {
  32. return r.repo.Create(storageTransferCount)
  33. }
  34. func (r *StorageTransferCountRepository) UpdateStorageTransferCount(storageTransferCount *StorageTransferCount) error {
  35. return r.repo.Update(storageTransferCount)
  36. }
  37. func (r *StorageTransferCountRepository) GetStorageTransferCountByID(id int) (*StorageTransferCount, error) {
  38. var storageTransferCount StorageTransferCount
  39. err := r.repo.GetByID(uint(id), &storageTransferCount)
  40. if err != nil {
  41. return nil, err
  42. }
  43. return &storageTransferCount, nil
  44. }
  45. func (r *StorageTransferCountRepository) GetStorageTransferCountByObjectID(objectID int64) ([]StorageTransferCount, error) {
  46. var storageTransferCounts []StorageTransferCount
  47. query := "SELECT * FROM storagetransfercount WHERE ObjectID = ?"
  48. err := r.repo.db.Raw(query, objectID).Scan(&storageTransferCounts).Error
  49. if err != nil {
  50. return nil, err
  51. }
  52. return storageTransferCounts, nil
  53. }
  54. func (r *StorageTransferCountRepository) GetAllStorageTransferCounts() ([]StorageTransferCount, error) {
  55. var storageTransferCounts []StorageTransferCount
  56. err := r.repo.GetAll(&storageTransferCounts)
  57. if err != nil {
  58. return nil, err
  59. }
  60. return storageTransferCounts, nil
  61. }
  62. type BlockTransferWatcher struct {
  63. Name string
  64. }
  65. func (w *BlockTransferWatcher) OnEvent(event sysevent.SysEvent) {
  66. repoDist := NewBlockDistributionRepository(DB)
  67. repoStorage := NewStorageRepository(DB)
  68. repoStorageTrans := NewStorageTransferCountRepository(DB)
  69. repoObject := NewObjectRepository(DB)
  70. if event.Category == "blockTransfer" {
  71. if blockTransfer, ok := event.Body.(*stgmod.BodyBlockTransfer); ok {
  72. for _, change := range blockTransfer.BlockChanges {
  73. objectID, _ := strconv.ParseInt(string(blockTransfer.ObjectID), 10, 64)
  74. object, _ := repoObject.GetObjectByID(objectID)
  75. index, _ := strconv.ParseInt(change.Index, 10, 64)
  76. sourceStorageID, _ := strconv.ParseInt(string(change.SourceStorageID), 10, 64)
  77. targetStorageID, _ := strconv.ParseInt(string(change.TargetStorageID), 10, 64)
  78. newDataCount, _ := strconv.ParseInt(change.DataTransferCount, 10, 64)
  79. switch change.Type {
  80. case "0": //拷贝
  81. //查询出存储在数据库中的BlockDistribution信息
  82. blockSource, errSource := repoDist.GetBlockDistributionByIndex(objectID, index, sourceStorageID)
  83. //没有记录就将source和target的信息都保存到库中
  84. if errors.Is(errSource, gorm.ErrRecordNotFound) {
  85. err := repoDist.CreateBlockDistribution(&BlockDistribution{
  86. ObjectID: objectID,
  87. Type: change.BlockType,
  88. Index: index,
  89. StorageID: sourceStorageID,
  90. Status: StatusNow,
  91. Timestamp: time.Now(),
  92. })
  93. if err != nil {
  94. log.Printf("Error create source blockdistribution: %v", err)
  95. }
  96. } else {
  97. //有数据则新增一条storageID为targetStorageID的记录,同时更新状态
  98. err := repoDist.CreateBlockDistribution(&BlockDistribution{
  99. ObjectID: blockSource.ObjectID,
  100. Type: change.BlockType,
  101. Index: index,
  102. StorageID: targetStorageID,
  103. Status: StatusNow,
  104. Timestamp: time.Now(),
  105. })
  106. if err != nil {
  107. log.Printf("Error update blockdistribution: %v", err)
  108. }
  109. //复制完成之后增加的dataCount要加到targetStorage的记录中
  110. storageOld, err := repoStorage.GetStorageByID(targetStorageID)
  111. if errors.Is(err, gorm.ErrRecordNotFound) {
  112. err = repoStorage.CreateStorage(&Storage{
  113. StorageID: cdssdk.StorageID(targetStorageID),
  114. DataCount: newDataCount,
  115. Timestamp: time.Now(),
  116. })
  117. if err != nil {
  118. log.Printf("Error increase datacount in targetstorage: %v", err)
  119. }
  120. } else {
  121. err = repoStorage.UpdateStorage(&Storage{
  122. StorageID: cdssdk.StorageID(targetStorageID),
  123. DataCount: storageOld.DataCount + newDataCount,
  124. Timestamp: time.Now(),
  125. })
  126. if err != nil {
  127. log.Printf("Error increase datacount in targetstorage: %v", err)
  128. }
  129. }
  130. }
  131. //新增记录到storageTransferCount表中
  132. err := repoStorageTrans.CreateStorageTransferCount(&StorageTransferCount{
  133. ObjectID: objectID,
  134. Status: int64(blockSource.Status),
  135. SourceStorageID: sourceStorageID,
  136. TargetStorageID: targetStorageID,
  137. DataTransferCount: newDataCount,
  138. Timestamp: time.Now(),
  139. })
  140. if err != nil {
  141. log.Printf("Error create StorageTransferCount : %v", err)
  142. }
  143. case "1": //编解码
  144. //删除所有的sourceBlock
  145. for _, sourceBlock := range change.SourceBlocks {
  146. sourceBlockIndex, _ := strconv.ParseInt(sourceBlock.Index, 10, 64)
  147. err := repoDist.DeleteBlockDistribution(objectID, sourceBlockIndex, sourceStorageID)
  148. if err != nil {
  149. log.Printf("Error delete blockdistribution: %v", err)
  150. }
  151. }
  152. //插入所有的targetBlock
  153. for _, targetBlock := range change.TargetBlocks {
  154. storageID, _ := strconv.ParseInt(string(targetBlock.StorageID), 10, 64)
  155. err := repoDist.CreateBlockDistribution(&BlockDistribution{
  156. ObjectID: objectID,
  157. Type: targetBlock.BlockType,
  158. Index: index,
  159. //直接保存到目标中心
  160. StorageID: storageID,
  161. Status: StatusNow,
  162. Timestamp: time.Now(),
  163. })
  164. if err != nil {
  165. log.Printf("Error create blockdistribution: %v", err)
  166. }
  167. }
  168. //新增记录到storageTransferCount表中
  169. err := repoStorageTrans.CreateStorageTransferCount(&StorageTransferCount{
  170. ObjectID: objectID,
  171. Status: int64(object.Status),
  172. SourceStorageID: sourceStorageID,
  173. TargetStorageID: targetStorageID,
  174. DataTransferCount: newDataCount,
  175. Timestamp: time.Now(),
  176. })
  177. if err != nil {
  178. log.Printf("Error create StorageTransferCount : %v", err)
  179. }
  180. case "2": //删除
  181. for _, block := range change.Blocks {
  182. storageID, _ := strconv.ParseInt(string(block.StorageID), 10, 64)
  183. changeIndex, _ := strconv.ParseInt(block.Index, 10, 64)
  184. err := repoDist.DeleteBlockDistribution(objectID, changeIndex, storageID)
  185. if err != nil {
  186. log.Printf("Error delete blockdistribution: %v", err)
  187. }
  188. }
  189. case "3": //更新
  190. for _, blockUpdate := range change.Blocks {
  191. //查询出存储在数据库中的BlockDistribution信息
  192. blockIndex, _ := strconv.ParseInt(blockUpdate.Index, 10, 64)
  193. blockOld, err := repoDist.GetBlockDistributionByIndex(objectID, blockIndex, sourceStorageID)
  194. newStorageID, _ := strconv.ParseInt(string(blockUpdate.StorageID), 10, 64)
  195. err = repoDist.UpdateBlockDistribution(&BlockDistribution{
  196. BlockID: blockOld.BlockID,
  197. ObjectID: blockOld.ObjectID,
  198. Type: blockUpdate.BlockType,
  199. Index: blockIndex,
  200. StorageID: newStorageID,
  201. Status: StatusNow,
  202. Timestamp: time.Now(),
  203. })
  204. if err != nil {
  205. log.Printf("Error delete blockdistribution: %v", err)
  206. }
  207. }
  208. default:
  209. break
  210. }
  211. }
  212. } else {
  213. fmt.Printf("Watcher %s: Unexpected Body type, expected *BodyStorageInfo, got %T\n", w.Name, event.Body)
  214. }
  215. } else {
  216. fmt.Printf("Watcher %s received an event with category %s\n", w.Name, event.Category)
  217. }
  218. }

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