github.com/songzhibin97/gkit@v1.2.13/distributed/backend/result/async_result.go (about) 1 package result 2 3 import ( 4 "context" 5 "errors" 6 "reflect" 7 "time" 8 9 "github.com/songzhibin97/gkit/distributed/backend" 10 "github.com/songzhibin97/gkit/distributed/task" 11 ) 12 13 // ErrBackendEmpty ... 14 var ErrBackendEmpty = errors.New("backend is empty") 15 16 // AsyncResult 异步结果 17 type AsyncResult struct { 18 Signature *task.Signature // Signature 任务签名 19 state *task.Status // state 任务状态 20 backend backend.Backend // backend 执行的实现 21 } 22 23 // ChainAsyncResult 链式调用任务结果返回 24 type ChainAsyncResult struct { 25 asyncResult []*AsyncResult 26 backend backend.Backend // backend 执行的实现 27 } 28 29 // GroupCallbackAsyncResult 具有回调任务的个任务组异步结果 30 type GroupCallbackAsyncResult struct { 31 groupAsyncResult []*AsyncResult 32 callbackAsyncResult *AsyncResult 33 backend backend.Backend // backend 执行的实现 34 } 35 36 // NewAsyncResult 创建异步任务返回结果 37 func NewAsyncResult(signature *task.Signature, backend backend.Backend) *AsyncResult { 38 return &AsyncResult{ 39 Signature: signature, 40 state: &task.Status{}, 41 backend: backend, 42 } 43 } 44 45 // NewChainAsyncResult 创建链式调用任务返回结果 46 func NewChainAsyncResult(chainAsyncResult []*task.Signature, backend backend.Backend) *ChainAsyncResult { 47 asyncResults := make([]*AsyncResult, 0, len(chainAsyncResult)) 48 for _, signature := range chainAsyncResult { 49 asyncResults = append(asyncResults, NewAsyncResult(signature, backend)) 50 } 51 return &ChainAsyncResult{ 52 asyncResult: asyncResults, 53 backend: backend, 54 } 55 } 56 57 // NewGroupCallbackAsyncResult 创建具有回调任务组的异步返回结果 58 func NewGroupCallbackAsyncResult(groupAsyncResult []*task.Signature, callbackAsyncResult *task.Signature, backend backend.Backend) *GroupCallbackAsyncResult { 59 asyncResults := make([]*AsyncResult, 0, len(groupAsyncResult)) 60 for _, signature := range groupAsyncResult { 61 asyncResults = append(asyncResults, NewAsyncResult(signature, backend)) 62 } 63 return &GroupCallbackAsyncResult{ 64 groupAsyncResult: asyncResults, 65 callbackAsyncResult: NewAsyncResult(callbackAsyncResult, backend), 66 backend: backend, 67 } 68 } 69 70 // Get 返回结果 71 func (asyncResult *AsyncResult) Get(sleepDuration time.Duration) ([]reflect.Value, error) { 72 for { 73 results, err := asyncResult.Monitor() 74 if results == nil && err == nil { 75 time.Sleep(sleepDuration) 76 } else { 77 return results, err 78 } 79 } 80 } 81 82 // GetWithTimeout 返回结果 带有超时时间 83 func (asyncResult *AsyncResult) GetWithTimeout(timeoutDuration, sleepDuration time.Duration) ([]reflect.Value, error) { 84 ctx, cancer := context.WithTimeout(context.Background(), timeoutDuration) 85 defer cancer() 86 for { 87 select { 88 case <-ctx.Done(): 89 return nil, ctx.Err() 90 default: 91 results, err := asyncResult.Monitor() 92 if results == nil && err == nil { 93 time.Sleep(sleepDuration) 94 } else { 95 return results, err 96 } 97 } 98 } 99 } 100 101 // Monitor 监视任务 102 func (asyncResult *AsyncResult) Monitor() ([]reflect.Value, error) { 103 if asyncResult.backend == nil { 104 return nil, ErrBackendEmpty 105 } 106 107 asyncResult.GetState() 108 if asyncResult.state.IsFailure() { 109 return nil, errors.New(asyncResult.state.Error) 110 } 111 if asyncResult.state.IsSuccess() { 112 return task.ReflectTaskResults(asyncResult.state.Results) 113 } 114 return nil, nil 115 } 116 117 // GetState 获取任务状态 118 func (asyncResult *AsyncResult) GetState() *task.Status { 119 if asyncResult.state.IsCompleted() { 120 return asyncResult.state 121 } 122 taskState, err := asyncResult.backend.GetStatus(asyncResult.Signature.ID) 123 if err == nil { 124 asyncResult.state = taskState 125 } 126 return asyncResult.state 127 } 128 129 // Get 返回结果 130 func (chainAsyncResult *ChainAsyncResult) Get(sleepDuration time.Duration) ([]reflect.Value, error) { 131 if chainAsyncResult.backend == nil { 132 return nil, ErrBackendEmpty 133 } 134 var ( 135 results []reflect.Value 136 err error 137 ) 138 for _, result := range chainAsyncResult.asyncResult { 139 results, err = result.Get(sleepDuration) 140 if err != nil { 141 return nil, err 142 } 143 } 144 return results, err 145 } 146 147 // GetWithTimeout 返回结果 带有超时时间 148 func (chainAsyncResult *ChainAsyncResult) GetWithTimeout(timeoutDuration, sleepDuration time.Duration) ([]reflect.Value, error) { 149 if chainAsyncResult.backend == nil { 150 return nil, ErrBackendEmpty 151 } 152 var ( 153 results []reflect.Value 154 err error 155 ln = len(chainAsyncResult.asyncResult) 156 lastResult = chainAsyncResult.asyncResult[ln-1] 157 ) 158 ctx, cancel := context.WithTimeout(context.Background(), timeoutDuration) 159 defer cancel() 160 for { 161 select { 162 case <-ctx.Done(): 163 return nil, ctx.Err() 164 default: 165 for _, result := range chainAsyncResult.asyncResult { 166 _, err = result.Monitor() 167 if err != nil { 168 return nil, err 169 } 170 } 171 results, err = lastResult.Monitor() 172 if err != nil { 173 return nil, err 174 } 175 if results != nil { 176 return results, err 177 } 178 time.Sleep(sleepDuration) 179 } 180 } 181 } 182 183 // Get 返回结果 184 func (groupCallbackAsyncResult *GroupCallbackAsyncResult) Get(sleepDuration time.Duration) ([]reflect.Value, error) { 185 if groupCallbackAsyncResult.backend == nil { 186 return nil, ErrBackendEmpty 187 } 188 var err error 189 for _, result := range groupCallbackAsyncResult.groupAsyncResult { 190 _, err = result.Get(sleepDuration) 191 if err != nil { 192 return nil, err 193 } 194 } 195 return groupCallbackAsyncResult.callbackAsyncResult.Get(sleepDuration) 196 } 197 198 // GetWithTimeout 返回结果 带有超时时间 199 func (groupCallbackAsyncResult *GroupCallbackAsyncResult) GetWithTimeout(timeoutDuration, sleepDuration time.Duration) ([]reflect.Value, error) { 200 if groupCallbackAsyncResult.backend == nil { 201 return nil, ErrBackendEmpty 202 } 203 var ( 204 results []reflect.Value 205 err error 206 ) 207 ctx, cancel := context.WithTimeout(context.Background(), timeoutDuration) 208 defer cancel() 209 for { 210 select { 211 case <-ctx.Done(): 212 return nil, ctx.Err() 213 default: 214 for _, result := range groupCallbackAsyncResult.groupAsyncResult { 215 _, err = result.Monitor() 216 if err != nil { 217 return nil, err 218 } 219 } 220 results, err = groupCallbackAsyncResult.callbackAsyncResult.Monitor() 221 if err != nil { 222 return nil, err 223 } 224 if results != nil { 225 return results, err 226 } 227 time.Sleep(sleepDuration) 228 } 229 } 230 }