gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/lifecycle.v2/future/future.go (about)

     1  package future
     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] func(value V)
    53  
    54  func (f CallbackFuture[V]) Complete(value V) {
    55  	f(value)
    56  }
    57  
    58  type AtomicCallbackFuture[V any] struct {
    59  	callback atomic.Pointer[func(value V)]
    60  	value    atomic.Pointer[V]
    61  	once     atomic.Bool
    62  	done     atomic.Bool
    63  }
    64  
    65  func NewAtomicCallbackFuture[V any](callback func(value V)) *AtomicCallbackFuture[V] {
    66  	future := new(AtomicCallbackFuture[V])
    67  	if callback != nil {
    68  		future.callback.Store(&callback)
    69  	}
    70  	return future
    71  }
    72  
    73  func (f *AtomicCallbackFuture[V]) Complete(value V) {
    74  	if f.once.CompareAndSwap(false, true) {
    75  		f.value.Store(&value)
    76  		if callback := f.callback.Load(); callback != nil && f.done.CompareAndSwap(false, true) {
    77  			(*callback)(value)
    78  		}
    79  	}
    80  }
    81  
    82  func (f *AtomicCallbackFuture[V]) SetCallback(callback func(value V)) {
    83  	f.callback.Store(&callback)
    84  	if value := f.value.Load(); value != nil && f.done.CompareAndSwap(false, true) {
    85  		callback(*value)
    86  	}
    87  }
    88  
    89  type Futures[V any] []Future[V]
    90  
    91  func (fs Futures[V]) Complete(value V) {
    92  	for _, future := range fs {
    93  		future.Complete(value)
    94  	}
    95  }
    96  
    97  type SyncFutures[V any] struct {
    98  	futures Futures[V]
    99  	sync.Mutex
   100  }
   101  
   102  func NewSyncFutures[V any]() *SyncFutures[V] {
   103  	return new(SyncFutures[V])
   104  }
   105  
   106  func (f *SyncFutures[V]) Append(future Future[V]) {
   107  	if future == nil {
   108  		return
   109  	}
   110  	lock.LockDo(f, func() { f.futures = append(f.futures, future) })
   111  }
   112  
   113  func (f *SyncFutures[V]) LoadAndReset() Futures[V] {
   114  	return lock.LockGet(f, func() (futures Futures[V]) {
   115  		futures = append(futures, f.futures...)
   116  		f.futures = f.futures[:0]
   117  		return
   118  	})
   119  }
   120  
   121  type WaitGroupFuture[V any] struct {
   122  	wg sync.WaitGroup
   123  }
   124  
   125  func (f *WaitGroupFuture[V]) Add(delta int) *WaitGroupFuture[V] {
   126  	f.wg.Add(delta)
   127  	return f
   128  }
   129  
   130  func (f *WaitGroupFuture[V]) Complete(value V) {
   131  	f.wg.Done()
   132  }
   133  
   134  func (f *WaitGroupFuture[V]) Wait() {
   135  	f.wg.Wait()
   136  }