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.

service.go 3.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package service
  2. import (
  3. "fmt"
  4. "time"
  5. "gitlink.org.cn/cloudream/common/pkg/distlock"
  6. clientv3 "go.etcd.io/etcd/client/v3"
  7. )
  8. const (
  9. LOCK_REQUEST_DATA_PREFIX = "/distlock/lockRequest/data"
  10. LOCK_REQUEST_INDEX = "/distlock/lockRequest/index"
  11. LOCK_REQUEST_LOCK_NAME = "/distlock/lockRequest/lock"
  12. )
  13. type lockData struct {
  14. Path []string `json:"path"`
  15. Name string `json:"name"`
  16. Target string `json:"target"`
  17. }
  18. type lockRequestData struct {
  19. ID string `json:"id"`
  20. Locks []lockData `json:"locks"`
  21. }
  22. type Service struct {
  23. cfg *distlock.Config
  24. etcdCli *clientv3.Client
  25. mainActor *mainActor
  26. providersActor *providersActor
  27. watchEtcdActor *watchEtcdActor
  28. leaseActor *leaseActor
  29. }
  30. func NewService(cfg *distlock.Config) (*Service, error) {
  31. etcdCli, err := clientv3.New(clientv3.Config{
  32. Endpoints: []string{cfg.EtcdAddress},
  33. Username: cfg.EtcdUsername,
  34. Password: cfg.EtcdPassword,
  35. })
  36. if err != nil {
  37. return nil, fmt.Errorf("new etcd client failed, err: %w", err)
  38. }
  39. mainActor := newMainActor()
  40. providersActor := newProvidersActor()
  41. watchEtcdActor := newWatchEtcdActor()
  42. leaseActor := newLeaseActor()
  43. mainActor.Init(watchEtcdActor, providersActor)
  44. providersActor.Init()
  45. watchEtcdActor.Init(providersActor)
  46. leaseActor.Init(mainActor)
  47. return &Service{
  48. cfg: cfg,
  49. etcdCli: etcdCli,
  50. mainActor: mainActor,
  51. providersActor: providersActor,
  52. watchEtcdActor: watchEtcdActor,
  53. leaseActor: leaseActor,
  54. }, nil
  55. }
  56. // Acquire 请求一批锁。成功后返回锁请求ID
  57. func (svc *Service) Acquire(req distlock.LockRequest) (string, error) {
  58. reqID, err := svc.mainActor.Acquire(req)
  59. if err != nil {
  60. return "", err
  61. }
  62. // TODO 不影响结果,但考虑打日志
  63. svc.leaseActor.Add(reqID, time.Duration(svc.cfg.LockRequestLeaseTimeSec)*time.Second)
  64. return reqID, nil
  65. }
  66. // Renew 续约锁
  67. func (svc *Service) Renew(reqID string) error {
  68. return svc.leaseActor.Renew(reqID, time.Duration(svc.cfg.LockRequestLeaseTimeSec)*time.Second)
  69. }
  70. // Release 释放锁
  71. func (svc *Service) Release(reqID string) error {
  72. err := svc.mainActor.Release(reqID)
  73. // TODO 不影响结果,但考虑打日志
  74. svc.leaseActor.Remove(reqID)
  75. return err
  76. }
  77. func (svc *Service) Serve() error {
  78. go func() {
  79. // TODO 处理错误
  80. svc.providersActor.Serve()
  81. }()
  82. go func() {
  83. // TODO 处理错误
  84. svc.watchEtcdActor.Serve()
  85. }()
  86. go func() {
  87. // TODO 处理错误
  88. svc.mainActor.Serve()
  89. }()
  90. go func() {
  91. // TODO 处理错误
  92. svc.leaseActor.Server()
  93. }()
  94. err := svc.mainActor.ReloadEtcdData()
  95. if err != nil {
  96. // TODO 关闭其他的Actor,或者更好的错误处理方式
  97. return fmt.Errorf("init data failed, err: %w", err)
  98. }
  99. err = svc.watchEtcdActor.StartWatching()
  100. if err != nil {
  101. // TODO 关闭其他的Actor,或者更好的错误处理方式
  102. return fmt.Errorf("start watching etcd failed, err: %w", err)
  103. }
  104. err = svc.leaseActor.StartChecking()
  105. if err != nil {
  106. // TODO 关闭其他的Actor,或者更好的错误处理方式
  107. return fmt.Errorf("start checking lease failed, err: %w", err)
  108. }
  109. // TODO 临时解决办法
  110. ch := make(chan any)
  111. <-ch
  112. return nil
  113. }

公共库

Contributors (1)