You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
1.5 KiB

  1. package broker
  2. import (
  3. "sync"
  4. "time"
  5. "github.com/chrislusf/seaweedfs/weed/util/log_buffer"
  6. )
  7. type TopicPartition struct {
  8. Namespace string
  9. Topic string
  10. Partition int32
  11. }
  12. type TopicLock struct {
  13. sync.Mutex
  14. subscriberCount int
  15. publisherCount int
  16. logBuffer *log_buffer.LogBuffer
  17. }
  18. type TopicLocks struct {
  19. sync.Mutex
  20. locks map[TopicPartition]*TopicLock
  21. }
  22. func NewTopicLocks() *TopicLocks {
  23. return &TopicLocks{
  24. locks: make(map[TopicPartition]*TopicLock),
  25. }
  26. }
  27. func (tl *TopicLocks) RequestSubscriberLock(partition TopicPartition) *TopicLock {
  28. tl.Lock()
  29. defer tl.Unlock()
  30. lock, found := tl.locks[partition]
  31. if !found {
  32. lock = &TopicLock{}
  33. tl.locks[partition] = lock
  34. }
  35. lock.subscriberCount++
  36. return lock
  37. }
  38. func (tl *TopicLocks) RequestPublisherLock(partition TopicPartition, flushFn func(startTime, stopTime time.Time, buf []byte)) *log_buffer.LogBuffer {
  39. tl.Lock()
  40. defer tl.Unlock()
  41. lock, found := tl.locks[partition]
  42. if !found {
  43. lock = &TopicLock{}
  44. tl.locks[partition] = lock
  45. }
  46. lock.publisherCount++
  47. cond := sync.NewCond(&lock.Mutex)
  48. lock.logBuffer = log_buffer.NewLogBuffer(time.Minute, flushFn, func() {
  49. cond.Broadcast()
  50. })
  51. return lock.logBuffer
  52. }
  53. func (tl *TopicLocks) ReleaseLock(partition TopicPartition, isPublisher bool) {
  54. tl.Lock()
  55. defer tl.Unlock()
  56. lock, found := tl.locks[partition]
  57. if !found {
  58. return
  59. }
  60. if isPublisher {
  61. lock.publisherCount--
  62. } else {
  63. lock.subscriberCount--
  64. }
  65. if lock.subscriberCount <= 0 && lock.publisherCount <= 0 {
  66. delete(tl.locks, partition)
  67. }
  68. }