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  }