-
Notifications
You must be signed in to change notification settings - Fork 0
/
future.go
55 lines (49 loc) · 1.46 KB
/
future.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package async
import (
"context"
)
// Future is a proxy for a result that is initially unknown.
//
// Use `new(Future[T])` to create a new Future. Use the package level ResolveFuture
// function to resolve a Latch.
//
// A Future must not be copied after first use.
type Future[T any] struct {
l Latch
v T
err error
}
// Done returns a channel that will be closed when the Future is resolved.
func (fut *Future[T]) Done() <-chan struct{} {
return fut.l.Done()
}
// Value blocks until the Future is resolved and returns resulting value and error.
//
// It is safe to call Value multiple times form multiple goroutines.
func (fut *Future[T]) Value() (T, error) {
Await(fut)
return fut.v, fut.err
}
// ValueCtx blocks until the Future is resolved or the context is canceled.
//
// If the context is canceled, the returned error will be the context's error. A canceled
// context does not necessarily mean that the Future was not resolved or will not resolve
// in the future.
//
// It is safe to call ValueCtx multiple times form multiple goroutines.
func (fut *Future[T]) ValueCtx(ctx context.Context) (T, error) {
if err := AwaitCtx(ctx, fut); err != nil {
var zero T
return zero, err
}
return fut.v, fut.err
}
// ResolveFuture resolves a Future and sets its value and error.
//
// Resolving a Future more than once will panic with ErrAlreadyResolved.
func ResolveFuture[T any](fut *Future[T], v T, err error) {
Resolve(&fut.l, func() {
fut.v = v
fut.err = err
})
}