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.

distlock.go 2.5 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package cmdline
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/samber/lo"
  6. "gitlink.org.cn/cloudream/common/pkgs/distlock"
  7. "gitlink.org.cn/cloudream/storage2/common/pkgs/distlock/lockprovider"
  8. )
  9. // DistLockLock 尝试获取分布式锁。
  10. // ctx: 命令上下文,包含执行命令所需的服务和配置。
  11. // lockData: 锁数据数组,每个元素包含锁的路径、名称和目标。
  12. // 返回值: 获取锁失败时返回错误。
  13. func DistLockLock(ctx CommandContext, lockData []string) error {
  14. req := distlock.LockRequest{}
  15. // 解析锁数据,填充请求结构体。
  16. for _, lock := range lockData {
  17. l, err := parseOneLock(lock)
  18. if err != nil {
  19. return fmt.Errorf("parse lock data %s failed, err: %w", lock, err)
  20. }
  21. req.Locks = append(req.Locks, l)
  22. }
  23. // 请求分布式锁。
  24. reqID, err := ctx.Cmdline.Svc.DistLock.Acquire(req)
  25. if err != nil {
  26. return fmt.Errorf("acquire locks failed, err: %w", err)
  27. }
  28. fmt.Printf("%s\n", reqID)
  29. return nil
  30. }
  31. // parseOneLock 解析单个锁数据。
  32. // lockData: 待解析的锁数据,格式为"路径/名称@目标字符串"。
  33. // 返回值: 解析得到的锁对象和可能的错误。
  34. func parseOneLock(lockData string) (distlock.Lock, error) {
  35. var lock distlock.Lock
  36. // 解析锁的路径、名称和目标。
  37. fullPathAndTarget := strings.Split(lockData, "@")
  38. if len(fullPathAndTarget) != 2 {
  39. return lock, fmt.Errorf("lock data must contains lock path, name and target")
  40. }
  41. pathAndName := strings.Split(fullPathAndTarget[0], "/")
  42. if len(pathAndName) < 2 {
  43. return lock, fmt.Errorf("lock data must contains lock path, name and target")
  44. }
  45. lock.Path = pathAndName[0 : len(pathAndName)-1]
  46. lock.Name = pathAndName[len(pathAndName)-1]
  47. // 解析目标字符串。
  48. target := lockprovider.NewStringLockTarget()
  49. comps := strings.Split(fullPathAndTarget[1], "/")
  50. for _, comp := range comps {
  51. target.Add(lo.Map(strings.Split(comp, "."), func(str string, index int) any { return str })...)
  52. }
  53. lock.Target = *target
  54. return lock, nil
  55. }
  56. // DistLockUnlock 释放分布式锁。
  57. // ctx: 命令上下文。
  58. // reqID: 请求ID,对应获取锁时返回的ID。
  59. // 返回值: 释放锁失败时返回错误。
  60. func DistLockUnlock(ctx CommandContext, reqID string) error {
  61. ctx.Cmdline.Svc.DistLock.Release(reqID)
  62. return nil
  63. }
  64. // 初始化命令行工具,注册分布式锁相关命令。
  65. func init() {
  66. commands.MustAdd(DistLockLock, "distlock", "lock")
  67. commands.MustAdd(DistLockUnlock, "distlock", "unlock")
  68. }

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