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.

lock_compatibility_table.go 3.1 kB

6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package lockprovider
  2. import (
  3. "fmt"
  4. "github.com/samber/lo"
  5. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/distlock/types"
  6. )
  7. const (
  8. LOCK_COMPATIBILITY_COMPATIBLE LockCompatibilityType = "Compatible"
  9. LOCK_COMPATIBILITY_UNCOMPATIBLE LockCompatibilityType = "Uncompatible"
  10. LOCK_COMPATIBILITY_SPECIAL LockCompatibilityType = "Special"
  11. )
  12. type HasSuchLockFn = func() bool
  13. // LockCompatibilitySpecialFn 判断锁与指定的锁名是否兼容
  14. type LockCompatibilitySpecialFn func(lock types.Lock, testLockName string) bool
  15. type LockCompatibilityType string
  16. type LockCompatibility struct {
  17. Type LockCompatibilityType
  18. SpecialFn LockCompatibilitySpecialFn
  19. }
  20. func LockCompatible() LockCompatibility {
  21. return LockCompatibility{
  22. Type: LOCK_COMPATIBILITY_COMPATIBLE,
  23. }
  24. }
  25. func LockUncompatible() LockCompatibility {
  26. return LockCompatibility{
  27. Type: LOCK_COMPATIBILITY_UNCOMPATIBLE,
  28. }
  29. }
  30. func LockSpecial(specialFn LockCompatibilitySpecialFn) LockCompatibility {
  31. return LockCompatibility{
  32. Type: LOCK_COMPATIBILITY_SPECIAL,
  33. SpecialFn: specialFn,
  34. }
  35. }
  36. type LockCompatibilityTableRow struct {
  37. LockName string
  38. HasSuchLockFn HasSuchLockFn
  39. Compatibilities []LockCompatibility
  40. }
  41. type LockCompatibilityTable struct {
  42. rows []LockCompatibilityTableRow
  43. rowIndex int
  44. }
  45. func (t *LockCompatibilityTable) Column(lockName string, hasSuchLock HasSuchLockFn) *LockCompatibilityTable {
  46. t.rows = append(t.rows, LockCompatibilityTableRow{
  47. LockName: lockName,
  48. HasSuchLockFn: hasSuchLock,
  49. })
  50. return t
  51. }
  52. func (t *LockCompatibilityTable) MustRow(comps ...LockCompatibility) {
  53. err := t.Row(comps...)
  54. if err != nil {
  55. panic(fmt.Sprintf("build lock compatibility table failed, err: %s", err.Error()))
  56. }
  57. }
  58. func (t *LockCompatibilityTable) Row(comps ...LockCompatibility) error {
  59. if t.rowIndex >= len(t.rows) {
  60. return fmt.Errorf("there should be no more rows in the table")
  61. }
  62. if len(comps) < len(t.rows) {
  63. return fmt.Errorf("the columns should equals the rows")
  64. }
  65. t.rows[t.rowIndex].Compatibilities = comps
  66. for i := 0; i < t.rowIndex-1; i++ {
  67. chkRowCeil := t.rows[t.rowIndex].Compatibilities[i]
  68. chkColCeil := t.rows[i].Compatibilities[t.rowIndex]
  69. if chkRowCeil.Type != chkColCeil.Type {
  70. return fmt.Errorf("value at %d, %d is not equals to at %d, %d", t.rowIndex, i, i, t.rowIndex)
  71. }
  72. }
  73. t.rowIndex++
  74. return nil
  75. }
  76. func (t *LockCompatibilityTable) Test(lock types.Lock) error {
  77. row, ok := lo.Find(t.rows, func(row LockCompatibilityTableRow) bool { return lock.Name == row.LockName })
  78. if !ok {
  79. return fmt.Errorf("unknow lock name %s", lock.Name)
  80. }
  81. for i, c := range row.Compatibilities {
  82. if c.Type == LOCK_COMPATIBILITY_COMPATIBLE {
  83. continue
  84. }
  85. if c.Type == LOCK_COMPATIBILITY_UNCOMPATIBLE {
  86. if t.rows[i].HasSuchLockFn() {
  87. return types.NewLockTargetBusyError(t.rows[i].LockName)
  88. }
  89. }
  90. if c.Type == LOCK_COMPATIBILITY_SPECIAL {
  91. if !c.SpecialFn(lock, t.rows[i].LockName) {
  92. return types.NewLockTargetBusyError(t.rows[i].LockName)
  93. }
  94. }
  95. }
  96. return nil
  97. }

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