github.com/matrixorigin/matrixone@v1.2.0/pkg/common/async/future.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package async 16 17 type pair struct { 18 value interface{} 19 err error 20 } 21 22 type Future struct { 23 c chan pair 24 ready bool 25 result pair 26 } 27 28 func AsyncCall(fn func(...interface{}) (interface{}, error), args ...interface{}) *Future { 29 var f Future 30 // Buffered size 1, so goroutine will not block. 31 f.c = make(chan pair, 1) 32 go func() { 33 v, e := fn(args...) 34 f.c <- pair{v, e} 35 }() 36 return &f 37 } 38 39 func (f *Future) BlockForReady() { 40 if !f.ready { 41 f.result = <-f.c 42 f.ready = true 43 } 44 } 45 46 func (f *Future) IsReady() bool { 47 if f.ready { 48 return true 49 } 50 select { 51 case f.result = <-f.c: 52 f.ready = true 53 default: 54 // no ready yet. 55 } 56 return f.ready 57 } 58 59 func (f *Future) Get() (interface{}, error) { 60 f.BlockForReady() 61 return f.result.value, f.result.err 62 } 63 64 func (f *Future) MustGet() interface{} { 65 v, e := f.Get() 66 if e != nil { 67 panic(e) 68 } 69 return v 70 }