github.com/tursom/GoCollections@v0.3.10/concurrent/collections/Sequence.go (about)

     1  /*
     2   * Copyright (c) 2022 tursom. All rights reserved.
     3   * Use of this source code is governed by a GPL-3
     4   * license that can be found in the LICENSE file.
     5   */
     6  
     7  package collections
     8  
     9  import (
    10  	"sync"
    11  
    12  	"github.com/tursom/GoCollections/concurrent"
    13  	"github.com/tursom/GoCollections/exceptions"
    14  	"github.com/tursom/GoCollections/lang"
    15  	"github.com/tursom/GoCollections/lang/atomic"
    16  )
    17  
    18  type (
    19  	// Sequence 一个用于并发生产场景下使消息有序的 Sequence
    20  	// 数据的接收顺序与 Sender 的生成顺序保持一致
    21  	Sequence[T any] struct {
    22  		lock  sync.Mutex
    23  		ch    lang.Channel[T]
    24  		head  *sequenceNode[T]
    25  		end   **sequenceNode[T]
    26  		close concurrent.Once
    27  	}
    28  
    29  	// SequenceSender 用于给 Sequence 发送信息
    30  	SequenceSender[T any] interface {
    31  		Send(value T)
    32  		Fail(cause exceptions.Exception)
    33  	}
    34  
    35  	sequenceNode[T any] struct {
    36  		sent     bool
    37  		value    T
    38  		cause    exceptions.Exception
    39  		sequence *Sequence[T]
    40  		next     *sequenceNode[T]
    41  	}
    42  )
    43  
    44  // channel 懒加载 Sequence channel
    45  func (s *Sequence[T]) channel() lang.Channel[T] {
    46  	// 经典懒加载单例写法
    47  	if s.ch == nil {
    48  		s.lock.Lock()
    49  		defer s.lock.Unlock()
    50  		if s.ch == nil {
    51  			s.ch = lang.NewChannel[T](16)
    52  		}
    53  	}
    54  
    55  	return s.ch
    56  }
    57  
    58  // Channel 获取用于读取 Sequence 数据的 channel
    59  func (s *Sequence[T]) Channel() lang.ReceiveChannel[T] {
    60  	return s.channel()
    61  }
    62  
    63  func (s *Sequence[T]) RawChannel() <-chan T {
    64  	return s.channel().RCh()
    65  }
    66  
    67  func (s *Sequence[T]) Send(msg T) {
    68  	s.Alloc().Send(msg)
    69  }
    70  
    71  // Alloc 预分配数据空间,数据将按照从 Sequence 分配时的顺序有序发送
    72  func (s *Sequence[T]) Alloc() SequenceSender[T] {
    73  	s.lock.Lock()
    74  	defer s.lock.Unlock()
    75  
    76  	node := &sequenceNode[T]{
    77  		sequence: s,
    78  	}
    79  	if s.end == nil {
    80  		s.end = &s.head
    81  	}
    82  	*s.end = node
    83  	s.end = &node.next
    84  	return node
    85  }
    86  
    87  // send 清空 Sequence 中可发送的消息
    88  func (s *Sequence[T]) send() {
    89  	if s.Closed() {
    90  		return
    91  	}
    92  	channel := s.channel()
    93  	s.lock.Lock()
    94  	defer s.lock.Unlock()
    95  
    96  	head := s.head
    97  	for head != nil && head.sent {
    98  		if head.cause == nil {
    99  			channel.Send(head.value)
   100  		} else {
   101  			s.Close()
   102  			panic(head.cause)
   103  		}
   104  		head = head.next
   105  		// 重置 s.head 防止并发安全问题产生
   106  		// 防止 sequenceNode.Send 判断自身是否是 head 产生的问题
   107  		atomic.StorePointer(&s.head, head)
   108  	}
   109  	if head == nil {
   110  		s.end = &s.head
   111  	}
   112  }
   113  
   114  func (s *Sequence[T]) Close() {
   115  	s.close.Do(func() {
   116  		s.channel().Close()
   117  	})
   118  }
   119  
   120  func (s *Sequence[T]) Closed() bool {
   121  	return s.close.IsDone()
   122  }
   123  
   124  func (s *sequenceNode[T]) Send(value T) {
   125  	if s.sequence.Closed() {
   126  		return
   127  	}
   128  	s.value = value
   129  	s.sent = true
   130  	if atomic.LoadPointer(&s.sequence.head) == s {
   131  		s.sequence.send()
   132  	}
   133  }
   134  
   135  func (s *sequenceNode[T]) Fail(cause exceptions.Exception) {
   136  	if s.sequence.Closed() {
   137  		return
   138  	}
   139  	s.cause = cause
   140  	s.sent = true
   141  	if atomic.LoadPointer(&s.sequence.head) == s {
   142  		s.sequence.send()
   143  	}
   144  }