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  }