gitea源码

globallock.go 2.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright 2024 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package globallock
  4. import (
  5. "context"
  6. "sync"
  7. "code.gitea.io/gitea/modules/setting"
  8. )
  9. var (
  10. defaultLocker Locker
  11. initOnce sync.Once
  12. initFunc = func() {
  13. switch setting.GlobalLock.ServiceType {
  14. case "redis":
  15. defaultLocker = NewRedisLocker(setting.GlobalLock.ServiceConnStr)
  16. case "memory":
  17. fallthrough
  18. default:
  19. defaultLocker = NewMemoryLocker()
  20. }
  21. } // define initFunc as a variable to make it possible to change it in tests
  22. )
  23. // DefaultLocker returns the default locker.
  24. func DefaultLocker() Locker {
  25. initOnce.Do(func() {
  26. initFunc()
  27. })
  28. return defaultLocker
  29. }
  30. // Lock tries to acquire a lock for the given key, it uses the default locker.
  31. // Read the documentation of Locker.Lock for more information about the behavior.
  32. func Lock(ctx context.Context, key string) (ReleaseFunc, error) {
  33. return DefaultLocker().Lock(ctx, key)
  34. }
  35. // TryLock tries to acquire a lock for the given key, it uses the default locker.
  36. // Read the documentation of Locker.TryLock for more information about the behavior.
  37. func TryLock(ctx context.Context, key string) (bool, ReleaseFunc, error) {
  38. return DefaultLocker().TryLock(ctx, key)
  39. }
  40. // LockAndDo tries to acquire a lock for the given key and then calls the given function.
  41. // It uses the default locker, and it will return an error if failed to acquire the lock.
  42. func LockAndDo(ctx context.Context, key string, f func(context.Context) error) error {
  43. release, err := Lock(ctx, key)
  44. if err != nil {
  45. return err
  46. }
  47. defer release()
  48. return f(ctx)
  49. }
  50. // TryLockAndDo tries to acquire a lock for the given key and then calls the given function.
  51. // It uses the default locker, and it will return false if failed to acquire the lock.
  52. func TryLockAndDo(ctx context.Context, key string, f func(context.Context) error) (bool, error) {
  53. ok, release, err := TryLock(ctx, key)
  54. if err != nil {
  55. return false, err
  56. }
  57. defer release()
  58. if !ok {
  59. return false, nil
  60. }
  61. return true, f(ctx)
  62. }