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 2.9 kB

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

公共库

Contributors (1)