Skip to content

Instantly share code, notes, and snippets.

@jonbodner
Created August 24, 2017 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonbodner/8c7a67c76f9591be74f80ce62911f552 to your computer and use it in GitHub Desktop.
Save jonbodner/8c7a67c76f9591be74f80ce62911f552 to your computer and use it in GitHub Desktop.
future-blog-post-15
func New(inFunc Process) Interface {
return newInner(make(chan struct{}), &sync.Once{}, inFunc)
}
func newInner(cancelChan chan struct{}, o *sync.Once, inFunc Process) Interface {
f := futureImpl{
done: make(chan struct{}),
cancel: cancelChan,
o: o,
}
go func() {
go func() {
f.val, f.err = inFunc()
close(f.done)
}()
select {
case <-f.done:
//do nothing, just waiting to see which will happen first
case <-f.cancel:
//do nothing, leave val and err nil
}
}()
return &f
}
func (f *futureImpl) Then(next Step) Interface {
nextFuture := newInner(f.cancel, f.o, func() (interface{}, error) {
result, err := f.Get()
if f.IsCancelled() || err != nil {
return result, err
}
return next(result)
})
return nextFuture
}
func (f *futureImpl) Get() (interface{}, error) {
select {
case <-f.done:
return f.val, f.err
case <-f.cancel:
//on cancel, just fall out
}
return nil, nil
}
func (f *futureImpl) GetUntil(d time.Duration) (interface{}, bool, error) {
select {
case <-f.done:
val, err := f.Get()
return val, false, err
case <-time.After(d):
return nil, true, nil
case <-f.cancel:
//on cancel, just fall out
}
return nil, false, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment