gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/lifecycle/future.go (about) 1 package lifecycle 2 3 import ( 4 "gitee.com/sy_183/go-common/lock" 5 "sync" 6 "sync/atomic" 7 ) 8 9 type Future[V any] interface { 10 Complete(value V) 11 } 12 13 type WaitableFuture[V any] interface { 14 Future[V] 15 16 Wait() V 17 } 18 19 type NopFuture[V any] struct{} 20 21 func (f NopFuture[V]) Complete(value V) {} 22 23 type ChanFuture[V any] chan V 24 25 func (c ChanFuture[V]) Complete(value V) { c <- value } 26 func (c ChanFuture[V]) Wait() V { return <-c } 27 28 type WaiterFuture[V any] struct { 29 waiter sync.WaitGroup 30 value V 31 once atomic.Bool 32 } 33 34 func NewWaiterFuture[V any]() *WaiterFuture[V] { 35 future := new(WaiterFuture[V]) 36 future.waiter.Add(1) 37 return future 38 } 39 40 func (w *WaiterFuture[V]) Complete(value V) { 41 if w.once.CompareAndSwap(false, true) { 42 w.value = value 43 w.waiter.Done() 44 } 45 } 46 47 func (w *WaiterFuture[V]) Wait() V { 48 w.waiter.Wait() 49 return w.value 50 } 51 52 type CallbackFuture[V any] struct { 53 callback atomic.Pointer[func(value V)] 54 value atomic.Pointer[V] 55 once atomic.Bool 56 done atomic.Bool 57 } 58 59 func NewCallbackFuture[V any](callback func(value V)) *CallbackFuture[V] { 60 future := new(CallbackFuture[V]) 61 if callback != nil { 62 future.callback.Store(&callback) 63 } 64 return future 65 } 66 67 func (f *CallbackFuture[V]) Complete(value V) { 68 if f.once.CompareAndSwap(false, true) { 69 f.value.Store(&value) 70 if callback := f.callback.Load(); callback != nil && f.done.CompareAndSwap(false, true) { 71 (*callback)(value) 72 } 73 } 74 } 75 76 func (f *CallbackFuture[V]) SetCallback(callback func(value V)) { 77 f.callback.Store(&callback) 78 if value := f.value.Load(); value != nil && f.done.CompareAndSwap(false, true) { 79 callback(*value) 80 } 81 } 82 83 type Futures[V any] []Future[V] 84 85 func (fs Futures[V]) Complete(value V) { 86 for _, future := range fs { 87 future.Complete(value) 88 } 89 } 90 91 type SyncFutures[V any] struct { 92 futures Futures[V] 93 sync.Mutex 94 } 95 96 func NewSyncFutures[V any]() *SyncFutures[V] { 97 return new(SyncFutures[V]) 98 } 99 100 func (f *SyncFutures[V]) Append(future Future[V]) { 101 if future == nil { 102 return 103 } 104 lock.LockDo(f, func() { f.futures = append(f.futures, future) }) 105 } 106 107 func (f *SyncFutures[V]) LoadAndReset() Futures[V] { 108 return lock.LockGet(f, func() (futures Futures[V]) { 109 futures = append(futures, f.futures...) 110 f.futures = f.futures[:0] 111 return 112 }) 113 }