func (ptree *ptree) initPending() { signaler := make(chan interface{}) future := futures.New(signaler, 30*time.Minute) ptree.pending = &pending{ signal: future, signaler: signaler, } }
// getNode will return a Node matching the provided id. An error is returned // if the cacher could not go to the persister or the node could not be found. // All found nodes are cached so subsequent calls should be faster than // the initial. This blocks until the node is loaded, but is also threadsafe. func (c *cacher) getNode(t *Tr, key ID, useCache bool) (*Node, error) { if !useCache { return c.loadNode(t, key) } c.lock.Lock() future, ok := c.cache[string(key)] if ok { c.lock.Unlock() ifc, err := future.GetResult() if err != nil { return nil, err } return ifc.(*Node), nil } completer := make(chan interface{}, 1) future = futures.New(completer, 30*time.Second) c.cache[string(key)] = future c.lock.Unlock() go c.asyncLoadNode(t, key, completer) ifc, err := future.GetResult() if err != nil { c.deleteFromCache(key) return nil, err } if err, ok := ifc.(error); ok { c.deleteFromCache(key) return nil, err } return ifc.(*Node), nil }