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.

103 lines
3.1 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  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. // AddTopicPartition adds a topic to the local topic manager
  19. func (manager *LocalTopicManager) AddTopicPartition(topic Topic, localPartition *LocalPartition) {
  20. localTopic, ok := manager.topics.Get(topic.String())
  21. if !ok {
  22. localTopic = &LocalTopic{
  23. Topic: topic,
  24. Partitions: make([]*LocalPartition, 0),
  25. }
  26. }
  27. if !manager.topics.SetIfAbsent(topic.String(), localTopic) {
  28. localTopic, _ = manager.topics.Get(topic.String())
  29. }
  30. if localTopic.findPartition(localPartition.Partition) != nil {
  31. return
  32. }
  33. localTopic.Partitions = append(localTopic.Partitions, localPartition)
  34. }
  35. // GetTopic gets a topic from the local topic manager
  36. func (manager *LocalTopicManager) GetTopicPartition(topic Topic, partition Partition) *LocalPartition {
  37. localTopic, ok := manager.topics.Get(topic.String())
  38. if !ok {
  39. return nil
  40. }
  41. return localTopic.findPartition(partition)
  42. }
  43. // RemoveTopic removes a topic from the local topic manager
  44. func (manager *LocalTopicManager) RemoveTopic(topic Topic) {
  45. manager.topics.Remove(topic.String())
  46. }
  47. func (manager *LocalTopicManager) RemoveTopicPartition(topic Topic, partition Partition) (removed bool) {
  48. localTopic, ok := manager.topics.Get(topic.String())
  49. if !ok {
  50. return false
  51. }
  52. return localTopic.removePartition(partition)
  53. }
  54. func (manager *LocalTopicManager) CollectStats(duration time.Duration) *mq_pb.BrokerStats {
  55. stats := &mq_pb.BrokerStats{
  56. Stats: make(map[string]*mq_pb.TopicPartitionStats),
  57. }
  58. // collect current broker's cpu usage
  59. // this needs to be in front, so the following stats can be more accurate
  60. usages, err := cpu.Percent(duration, false)
  61. if err == nil && len(usages) > 0 {
  62. stats.CpuUsagePercent = int32(usages[0])
  63. }
  64. // collect current broker's topics and partitions
  65. manager.topics.IterCb(func(topic string, localTopic *LocalTopic) {
  66. for _, localPartition := range localTopic.Partitions {
  67. topicPartition := &TopicPartition{
  68. Topic: Topic{Namespace: localTopic.Namespace, Name: localTopic.Name},
  69. Partition: Partition{
  70. RingSize: localPartition.RingSize,
  71. RangeStart: localPartition.RangeStart,
  72. RangeStop: localPartition.RangeStop,
  73. },
  74. }
  75. stats.Stats[topicPartition.String()] = &mq_pb.TopicPartitionStats{
  76. Topic: &mq_pb.Topic{
  77. Namespace: string(localTopic.Namespace),
  78. Name: localTopic.Name,
  79. },
  80. Partition: &mq_pb.Partition{
  81. RingSize: localPartition.RingSize,
  82. RangeStart: localPartition.RangeStart,
  83. RangeStop: localPartition.RangeStop,
  84. },
  85. ConsumerCount: localPartition.ConsumerCount,
  86. }
  87. // fmt.Printf("collect topic %+v partition %+v\n", topicPartition, localPartition.Partition)
  88. }
  89. })
  90. return stats
  91. }