Skip to content

Instantly share code, notes, and snippets.

@kimathie
Created April 12, 2023 18:19
Show Gist options
  • Save kimathie/df0989b5a6554671beb604c0a440e425 to your computer and use it in GitHub Desktop.
Save kimathie/df0989b5a6554671beb604c0a440e425 to your computer and use it in GitHub Desktop.
An implementation of a future in go
import (
"context"
"time"
)
type Task[t any] func() (t, error)
type result[t any] struct {
Error error
Success t
}
type Future[t any] interface {
Cancel()
Get() result[t]
IsComplete() bool
}
type future[t any] struct {
done bool
task Task[t]
result chan result[t]
ctx context.Context
cancel context.CancelFunc
}
func NewFuture[t any](task Task[t], timeout time.Duration) Future[t] {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
f := &future[t]{
ctx: ctx,
cancel: cancel,
task: task,
result: make(chan result[t]),
}
return f
}
func (f *future[t]) Cancel() {
f.cancel()
}
func (f *future[t]) IsComplete() bool {
return f.done
}
func (f *future[t]) Get() (rs result[t]) {
defer func() { f.done = true }()
go func() {
success, err := f.task()
f.result <- result[t]{Success: success, Error: err}
}()
select {
case result := <-f.result:
return result
case <-f.ctx.Done():
return result[t]{Error: f.ctx.Err()}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment