Skip to content

Instantly share code, notes, and snippets.

@aslakknutsen
Created October 27, 2017 17:05
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 aslakknutsen/45b6cc5c9c2b7fa85b5d8a88bf9f81cf to your computer and use it in GitHub Desktop.
Save aslakknutsen/45b6cc5c9c2b7fa85b5d8a88bf9f81cf to your computer and use it in GitHub Desktop.
Multi level locked cache with Promise, single resovler
package middlewares
import (
"sync"
)
type Cache struct {
mux sync.Mutex
m map[string]Promise
}
func (c *Cache) Get(key string, resolver Resolver) Promise {
c.mux.Lock()
defer c.mux.Unlock()
if c.m == nil {
c.m = make(map[string]Promise)
}
if val, ok := c.m[key]; ok {
return val
}
val := &ResolverPromise{resolver: resolver}
c.m[key] = val
return val
}
type ResolverPromise struct {
mux sync.Mutex
resolver Resolver
resolved bool
value interface{}
err error
}
func (r *ResolverPromise) Get() (interface{}, error) {
r.mux.Lock()
defer r.mux.Unlock()
if r.resolved {
return r.value, r.err
}
wg := sync.WaitGroup{}
wg.Add(1)
go func(wg *sync.WaitGroup, resolver Resolver) {
r.value, r.err = resolver()
wg.Done()
}(&wg, r.resolver)
wg.Wait()
r.resolved = true
return r.value, r.err
}
type Resolver func() (interface{}, error)
type Promise interface {
Get() (interface{}, error)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment