github.com/tursom/GoCollections@v0.3.10/concurrent/future/Future.go (about) 1 package future 2 3 import ( 4 "github.com/tursom/GoCollections/exceptions" 5 "github.com/tursom/GoCollections/lang" 6 "github.com/tursom/GoCollections/util/time" 7 ) 8 9 type ( 10 Future[T any] interface { 11 Get() (T, exceptions.Exception) 12 GetT(timeout time.Duration) (T, exceptions.Exception) 13 IsDone() bool 14 IsCancelled() bool 15 Cancel() bool 16 } 17 18 Task[T any] interface { 19 Future[T] 20 Done(value T) 21 Fail(e exceptions.Exception) 22 } 23 24 futureState uint8 25 26 impl[T any] struct { 27 state futureState 28 value T 29 e exceptions.Exception 30 done chan futureState 31 canceller func() bool 32 } 33 ) 34 35 //goland:noinspection GoSnakeCaseUsage 36 const ( 37 futureState_start futureState = iota 38 futureState_done futureState = iota 39 futureState_canceled futureState = iota 40 ) 41 42 func Get[T any](future Future[T]) T { 43 get, e := future.Get() 44 if e != nil { 45 panic(e) 46 } 47 48 return get 49 } 50 51 func GetT[T any](future Future[T], timeout time.Duration) T { 52 get, e := future.GetT(timeout) 53 if e != nil { 54 panic(e) 55 } 56 57 return get 58 } 59 60 func New[T any](canceller func() bool) Task[T] { 61 return &impl[T]{ 62 done: make(chan futureState, 1), 63 canceller: canceller, 64 } 65 } 66 67 func (i *impl[T]) Done(value T) { 68 if i.IsDone() { 69 return 70 } 71 72 i.value = value 73 i.state = futureState_done 74 i.done <- futureState_done 75 } 76 77 func (i *impl[T]) Fail(e exceptions.Exception) { 78 if i.IsDone() { 79 return 80 } 81 82 i.e = e 83 i.state = futureState_done 84 i.done <- futureState_done 85 } 86 87 func (i *impl[T]) Get() (T, exceptions.Exception) { 88 if i.IsDone() { 89 return i.value, i.e 90 } 91 92 <-i.done 93 94 return i.value, i.e 95 } 96 97 func (i *impl[T]) GetT(timeout time.Duration) (T, exceptions.Exception) { 98 if i.IsDone() { 99 return i.value, i.e 100 } 101 102 select { 103 case i.state = <-i.done: 104 case <-time.After(timeout): 105 return lang.Nil[T](), exceptions.NewTimeoutException( 106 "Future.GetT timeout", nil) 107 } 108 109 return i.value, i.e 110 } 111 112 func (i *impl[T]) IsDone() bool { 113 return i.state != futureState_start 114 } 115 116 func (i *impl[T]) IsCancelled() bool { 117 return i.state == futureState_canceled 118 } 119 120 func (i *impl[T]) Cancel() bool { 121 if i.IsDone() { 122 return false 123 } 124 125 if !i.canceller() { 126 return false 127 } 128 129 i.state = futureState_canceled 130 i.done <- futureState_canceled 131 return true 132 }