func (l *loader) entry(req loaderReq) (*loaderEntry, bool) {
	if v, ok := l.cache[req.id]; ok {
		req.ch <- v
		return v, false
	}
	e := &loaderEntry{
		id:   req.id,
		done: make(chan struct{}),
	}
	l.cache[req.id] = e
	req.ch <- e
	return e, true
}
entry will return the current entry or create a new one in the map.
It passes the new or existing loaderEntry to the requester.
package dataloader
import (
	"context"
	"sync"
	"time"
	"go.opencensus.io/trace"
)
type loaderConfig struct {
	FetchFunc func(context.Context, []string) ([]interface{}, error)  
	IDFunc    func(interface{}) string                                
	Delay time.Duration  
	Max   int            
	Name string  
}
type loaderReq struct {
	id string
	ch chan *loaderEntry
}
type loaderEntry struct {
	id   string
	done chan struct{}
	err  error
	data interface{}
}
type loader struct {
	ctx    context.Context
	cancel func()
	cfg   loaderConfig
	cache map[string]*loaderEntry
	start sync.Once
	reqCh chan loaderReq
}
func newLoader(ctx context.Context, cfg loaderConfig) *loader {
	l := &loader{cfg: cfg}
	l.ctx, l.cancel = context.WithCancel(ctx)
	return l
}
func (l *loader) Close() error {
	l.start.Do(l.cancel)
	l.cancel()
	return nil
}
func (l *loader) init() {
	l.cache = make(map[string]*loaderEntry, l.cfg.Max)
	l.reqCh = make(chan loaderReq, l.cfg.Max)
	go l.loop()
}
func (l *loader) load(entries []*loaderEntry) []*loaderEntry {
	if len(entries) > l.cfg.Max {
		l.load(entries[:l.cfg.Max])
		return entries[l.cfg.Max:]
	}
	cpy := make([]*loaderEntry, len(entries))
	copy(cpy, entries)
	go func() {
		ctx, sp := trace.StartSpan(l.ctx, "Loader.Fetch/"+l.cfg.Name)
		defer sp.End()
		m := make(map[string]*loaderEntry, len(entries))
		ids := make([]string, len(entries))
		for i, e := range cpy {
			ids[i] = e.id
			m[e.id] = e
		}
		res, err := l.cfg.FetchFunc(ctx, ids)
		if err != nil {
			for _, e := range cpy {
				e.err = err
				close(e.done)
			}
			return
		}
		for i := range res {
			id := l.cfg.IDFunc(res[i])
			e := m[id]
			if e == nil {
				continue
			}
			e.data = res[i]
		}
		for _, e := range cpy {
			close(e.done)
		}
	}()
	return entries[:0]
}