Esempio n. 1
0
func (ptree *ptree) initPending() {
	signaler := make(chan interface{})
	future := futures.New(signaler, 30*time.Minute)
	ptree.pending = &pending{
		signal:   future,
		signaler: signaler,
	}
}
Esempio n. 2
0
// 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
}