Skip to content

Instantly share code, notes, and snippets.

@lenstr
Created July 27, 2018 07:49
Show Gist options
  • Save lenstr/3d7b0021fe57e823e88170ebe5d3cce8 to your computer and use it in GitHub Desktop.
Save lenstr/3d7b0021fe57e823e88170ebe5d3cce8 to your computer and use it in GitHub Desktop.
package concurrency
import (
"fmt"
"sync"
)
type Promise struct {
value interface{}
error error
resolved bool
mu *sync.RWMutex
fn func() (interface{}, error)
}
func NewPromise(fn func() (interface{}, error)) *Promise {
mu := new(sync.RWMutex)
promise := &Promise{
mu: mu,
fn: fn,
}
return promise
}
func (promise *Promise) Get() (interface{}, error) {
promise.mu.RLock()
if promise.resolved {
promise.mu.RUnlock()
return promise.value, promise.error
}
promise.mu.RUnlock()
promise.mu.Lock()
if promise.resolved {
promise.mu.Unlock()
return promise.value, promise.error
}
promise.value, promise.error = promise.run()
promise.resolved = true
promise.mu.Unlock()
return promise.value, promise.error
}
func (promise *Promise) run() (value interface{}, err error) {
defer func() {
if r := recover(); r != nil {
var ok bool
if err, ok = r.(error); !ok {
err = fmt.Errorf("panic: %v", r)
}
}
}()
return promise.fn()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment