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.
		
		
		
		
		
			
		
			
				
					
					
						
							113 lines
						
					
					
						
							3.0 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							113 lines
						
					
					
						
							3.0 KiB
						
					
					
				
								package topic
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"sync"
							 | 
						|
								
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/glog"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								type LocalTopic struct {
							 | 
						|
									Topic
							 | 
						|
									Partitions    []*LocalPartition
							 | 
						|
									partitionLock sync.RWMutex
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func NewLocalTopic(topic Topic) *LocalTopic {
							 | 
						|
									return &LocalTopic{
							 | 
						|
										Topic:      topic,
							 | 
						|
										Partitions: make([]*LocalPartition, 0),
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (localTopic *LocalTopic) findPartition(partition Partition) *LocalPartition {
							 | 
						|
									localTopic.partitionLock.RLock()
							 | 
						|
									defer localTopic.partitionLock.RUnlock()
							 | 
						|
								
							 | 
						|
									glog.V(4).Infof("findPartition searching for %s in %d partitions", partition.String(), len(localTopic.Partitions))
							 | 
						|
									for i, localPartition := range localTopic.Partitions {
							 | 
						|
										glog.V(4).Infof("Comparing partition[%d]: %s with target %s", i, localPartition.Partition.String(), partition.String())
							 | 
						|
										if localPartition.Partition.LogicalEquals(partition) {
							 | 
						|
											glog.V(4).Infof("Found matching partition at index %d", i)
							 | 
						|
											return localPartition
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
									glog.V(4).Infof("No matching partition found for %s", partition.String())
							 | 
						|
									return nil
							 | 
						|
								}
							 | 
						|
								func (localTopic *LocalTopic) removePartition(partition Partition) bool {
							 | 
						|
									localTopic.partitionLock.Lock()
							 | 
						|
									defer localTopic.partitionLock.Unlock()
							 | 
						|
								
							 | 
						|
									foundPartitionIndex := -1
							 | 
						|
									for i, localPartition := range localTopic.Partitions {
							 | 
						|
										if localPartition.Partition.LogicalEquals(partition) {
							 | 
						|
											foundPartitionIndex = i
							 | 
						|
											localPartition.Shutdown()
							 | 
						|
											break
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
									if foundPartitionIndex == -1 {
							 | 
						|
										return false
							 | 
						|
									}
							 | 
						|
									localTopic.Partitions = append(localTopic.Partitions[:foundPartitionIndex], localTopic.Partitions[foundPartitionIndex+1:]...)
							 | 
						|
									return true
							 | 
						|
								}
							 | 
						|
								func (localTopic *LocalTopic) addPartition(localPartition *LocalPartition) {
							 | 
						|
									localTopic.partitionLock.Lock()
							 | 
						|
									defer localTopic.partitionLock.Unlock()
							 | 
						|
									for _, partition := range localTopic.Partitions {
							 | 
						|
										if localPartition.Partition.LogicalEquals(partition.Partition) {
							 | 
						|
											return
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
									localTopic.Partitions = append(localTopic.Partitions, localPartition)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (localTopic *LocalTopic) closePartitionPublishers(unixTsNs int64) bool {
							 | 
						|
									var wg sync.WaitGroup
							 | 
						|
									for _, localPartition := range localTopic.Partitions {
							 | 
						|
										if localPartition.UnixTimeNs != unixTsNs {
							 | 
						|
											continue
							 | 
						|
										}
							 | 
						|
										wg.Add(1)
							 | 
						|
										go func(localPartition *LocalPartition) {
							 | 
						|
											defer wg.Done()
							 | 
						|
											localPartition.closePublishers()
							 | 
						|
										}(localPartition)
							 | 
						|
									}
							 | 
						|
									wg.Wait()
							 | 
						|
									return true
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (localTopic *LocalTopic) closePartitionSubscribers(unixTsNs int64) bool {
							 | 
						|
									var wg sync.WaitGroup
							 | 
						|
									for _, localPartition := range localTopic.Partitions {
							 | 
						|
										if localPartition.UnixTimeNs != unixTsNs {
							 | 
						|
											continue
							 | 
						|
										}
							 | 
						|
										wg.Add(1)
							 | 
						|
										go func(localPartition *LocalPartition) {
							 | 
						|
											defer wg.Done()
							 | 
						|
											localPartition.closeSubscribers()
							 | 
						|
										}(localPartition)
							 | 
						|
									}
							 | 
						|
									wg.Wait()
							 | 
						|
									return true
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (localTopic *LocalTopic) WaitUntilNoPublishers() {
							 | 
						|
									for {
							 | 
						|
										var wg sync.WaitGroup
							 | 
						|
										for _, localPartition := range localTopic.Partitions {
							 | 
						|
											wg.Add(1)
							 | 
						|
											go func(localPartition *LocalPartition) {
							 | 
						|
												defer wg.Done()
							 | 
						|
												localPartition.WaitUntilNoPublishers()
							 | 
						|
											}(localPartition)
							 | 
						|
										}
							 | 
						|
										wg.Wait()
							 | 
						|
										if len(localTopic.Partitions) == 0 {
							 | 
						|
											return
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								}
							 |