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.

bucket.go 3.2 kB

2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package services
  2. import (
  3. "fmt"
  4. "gitlink.org.cn/cloudream/common/pkg/distlock/reqbuilder"
  5. "gitlink.org.cn/cloudream/db/model"
  6. coormsg "gitlink.org.cn/cloudream/rabbitmq/message/coordinator"
  7. )
  8. type BucketService struct {
  9. *Service
  10. }
  11. func (svc *Service) BucketSvc() *BucketService {
  12. return &BucketService{Service: svc}
  13. }
  14. func (svc *BucketService) GetBucket(userID int, bucketID int) (model.Bucket, error) {
  15. // TODO
  16. panic("not implement yet")
  17. }
  18. func (svc *BucketService) GetUserBuckets(userID int) ([]model.Bucket, error) {
  19. resp, err := svc.coordinator.GetUserBuckets(coormsg.NewGetUserBucketsBody(userID))
  20. if err != nil {
  21. return nil, fmt.Errorf("get user buckets failed, err: %w", err)
  22. }
  23. if resp.IsFailed() {
  24. return nil, fmt.Errorf("create bucket objects failed, code: %s, message: %s", resp.ErrorCode, resp.ErrorMessage)
  25. }
  26. return resp.Body.Buckets, nil
  27. }
  28. func (svc *BucketService) GetBucketObjects(userID int, bucketID int) ([]model.Object, error) {
  29. resp, err := svc.coordinator.GetBucketObjects(coormsg.NewGetBucketObjectsBody(userID, bucketID))
  30. if err != nil {
  31. return nil, fmt.Errorf("get bucket objects failed, err: %w", err)
  32. }
  33. if resp.IsFailed() {
  34. return nil, fmt.Errorf("create bucket objects failed, code: %s, message: %s", resp.ErrorCode, resp.ErrorMessage)
  35. }
  36. return resp.Body.Objects, nil
  37. }
  38. func (svc *BucketService) CreateBucket(userID int, bucketName string) (int, error) {
  39. // TODO 只有阅读了系统操作的源码,才能知道要加哪些锁,但用户的命令可能会调用不止一个系统操作。
  40. // 因此加锁的操作还是必须在用户命令里完成,但具体加锁的内容,则需要被封装起来与系统操作放到一起,方便管理,避免分散改动。
  41. mutex, err := reqbuilder.NewBuilder().
  42. Metadata().Bucket().CreateOne(userID, bucketName).
  43. // TODO 可以考虑二次加锁,加的更精确
  44. UserBucket().CreateAny().
  45. MutexLock(svc.distlock)
  46. if err != nil {
  47. return 0, fmt.Errorf("acquire locks failed, err: %w", err)
  48. }
  49. defer mutex.Unlock()
  50. resp, err := svc.coordinator.CreateBucket(coormsg.NewCreateBucketBody(userID, bucketName))
  51. if err != nil {
  52. return 0, fmt.Errorf("request to coordinator failed, err: %w", err)
  53. }
  54. if resp.IsFailed() {
  55. return 0, fmt.Errorf("create bucket objects failed, code: %s, message: %s", resp.ErrorCode, resp.ErrorMessage)
  56. }
  57. return resp.Body.BucketID, nil
  58. }
  59. func (svc *BucketService) DeleteBucket(userID int, bucketID int) error {
  60. // TODO 检查用户是否有删除这个Bucket的权限。检查的时候可以只上UserBucket的Read锁
  61. mutex, err := reqbuilder.NewBuilder().
  62. Metadata().
  63. UserBucket().WriteAny().
  64. Bucket().WriteOne(bucketID).
  65. Object().WriteAny().
  66. ObjectRep().WriteAny().
  67. ObjectBlock().WriteAny().
  68. StorageObject().WriteAny().
  69. MutexLock(svc.distlock)
  70. if err != nil {
  71. return fmt.Errorf("acquire locks failed, err: %w", err)
  72. }
  73. defer mutex.Unlock()
  74. resp, err := svc.coordinator.DeleteBucket(coormsg.NewDeleteBucketBody(userID, bucketID))
  75. if err != nil {
  76. return fmt.Errorf("request to coordinator failed, err: %w", err)
  77. }
  78. if resp.IsFailed() {
  79. return fmt.Errorf("delete bucket failed, code: %s, message: %s", resp.ErrorCode, resp.ErrorMessage)
  80. }
  81. return nil
  82. }

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