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 }