local_manager.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package topic
  2. import (
  3. cmap "github.com/orcaman/concurrent-map/v2"
  4. "github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
  5. "github.com/shirou/gopsutil/v3/cpu"
  6. "time"
  7. )
  8. // LocalTopicManager manages topics on local broker
  9. type LocalTopicManager struct {
  10. topics cmap.ConcurrentMap[string, *LocalTopic]
  11. }
  12. // NewLocalTopicManager creates a new LocalTopicManager
  13. func NewLocalTopicManager() *LocalTopicManager {
  14. return &LocalTopicManager{
  15. topics: cmap.New[*LocalTopic](),
  16. }
  17. }
  18. // AddLocalPartition adds a topic to the local topic manager
  19. func (manager *LocalTopicManager) AddLocalPartition(topic Topic, localPartition *LocalPartition) {
  20. localTopic, ok := manager.topics.Get(topic.String())
  21. if !ok {
  22. localTopic = NewLocalTopic(topic)
  23. }
  24. if !manager.topics.SetIfAbsent(topic.String(), localTopic) {
  25. localTopic, _ = manager.topics.Get(topic.String())
  26. }
  27. if localTopic.findPartition(localPartition.Partition) != nil {
  28. return
  29. }
  30. localTopic.Partitions = append(localTopic.Partitions, localPartition)
  31. }
  32. // GetLocalPartition gets a topic from the local topic manager
  33. func (manager *LocalTopicManager) GetLocalPartition(topic Topic, partition Partition) *LocalPartition {
  34. localTopic, ok := manager.topics.Get(topic.String())
  35. if !ok {
  36. return nil
  37. }
  38. return localTopic.findPartition(partition)
  39. }
  40. // RemoveTopic removes a topic from the local topic manager
  41. func (manager *LocalTopicManager) RemoveTopic(topic Topic) {
  42. manager.topics.Remove(topic.String())
  43. }
  44. func (manager *LocalTopicManager) RemoveLocalPartition(topic Topic, partition Partition) (removed bool) {
  45. localTopic, ok := manager.topics.Get(topic.String())
  46. if !ok {
  47. return false
  48. }
  49. return localTopic.removePartition(partition)
  50. }
  51. func (manager *LocalTopicManager) ClosePublishers(topic Topic, unixTsNs int64) (removed bool) {
  52. localTopic, ok := manager.topics.Get(topic.String())
  53. if !ok {
  54. return false
  55. }
  56. return localTopic.closePartitionPublishers(unixTsNs)
  57. }
  58. func (manager *LocalTopicManager) CloseSubscribers(topic Topic, unixTsNs int64) (removed bool) {
  59. localTopic, ok := manager.topics.Get(topic.String())
  60. if !ok {
  61. return false
  62. }
  63. return localTopic.closePartitionSubscribers(unixTsNs)
  64. }
  65. func (manager *LocalTopicManager) CollectStats(duration time.Duration) *mq_pb.BrokerStats {
  66. stats := &mq_pb.BrokerStats{
  67. Stats: make(map[string]*mq_pb.TopicPartitionStats),
  68. }
  69. // collect current broker's cpu usage
  70. // this needs to be in front, so the following stats can be more accurate
  71. usages, err := cpu.Percent(duration, false)
  72. if err == nil && len(usages) > 0 {
  73. stats.CpuUsagePercent = int32(usages[0])
  74. }
  75. // collect current broker's topics and partitions
  76. manager.topics.IterCb(func(topic string, localTopic *LocalTopic) {
  77. for _, localPartition := range localTopic.Partitions {
  78. topicPartition := &TopicPartition{
  79. Topic: Topic{Namespace: localTopic.Namespace, Name: localTopic.Name},
  80. Partition: localPartition.Partition,
  81. }
  82. stats.Stats[topicPartition.String()] = &mq_pb.TopicPartitionStats{
  83. Topic: &mq_pb.Topic{
  84. Namespace: string(localTopic.Namespace),
  85. Name: localTopic.Name,
  86. },
  87. Partition: localPartition.Partition.ToPbPartition(),
  88. PublisherCount: int32(localPartition.Publishers.Size()),
  89. SubscriberCount: int32(localPartition.Subscribers.Size()),
  90. }
  91. // fmt.Printf("collect topic %+v partition %+v\n", topicPartition, localPartition.Partition)
  92. }
  93. })
  94. return stats
  95. }
  96. func (manager *LocalTopicManager) WaitUntilNoPublishers(topic Topic) {
  97. localTopic, ok := manager.topics.Get(topic.String())
  98. if !ok {
  99. return
  100. }
  101. localTopic.WaitUntilNoPublishers()
  102. }