|
@ -3,6 +3,7 @@ package loader |
|
|
import ( |
|
|
import ( |
|
|
"context" |
|
|
"context" |
|
|
"errors" |
|
|
"errors" |
|
|
|
|
|
"sync" |
|
|
"time" |
|
|
"time" |
|
|
|
|
|
|
|
|
"github.com/graph-gophers/dataloader" |
|
|
"github.com/graph-gophers/dataloader" |
|
@ -16,8 +17,11 @@ var ErrNotFound = errors.New("not found") |
|
|
// A Loader is a collection of data loaders and functions to act on them. It's supposed to be
|
|
|
// A Loader is a collection of data loaders and functions to act on them. It's supposed to be
|
|
|
// request-scoped, and will thus keep things cached indefinitely.
|
|
|
// request-scoped, and will thus keep things cached indefinitely.
|
|
|
type Loader struct { |
|
|
type Loader struct { |
|
|
|
|
|
mutex sync.Mutex |
|
|
ctx context.Context |
|
|
ctx context.Context |
|
|
loaders map[string]*dataloader.Loader |
|
|
loaders map[string]*dataloader.Loader |
|
|
|
|
|
|
|
|
|
|
|
primedKeys map[string]map[string]bool |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// New initializes the loader.
|
|
|
// New initializes the loader.
|
|
@ -29,6 +33,7 @@ func New() *Loader { |
|
|
"Character.nick": dataloader.NewBatchedLoader(characterNickBatch, dataloader.WithWait(time.Millisecond)), |
|
|
"Character.nick": dataloader.NewBatchedLoader(characterNickBatch, dataloader.WithWait(time.Millisecond)), |
|
|
"Channel.name": dataloader.NewBatchedLoader(channelNameBatch, dataloader.WithWait(time.Millisecond)), |
|
|
"Channel.name": dataloader.NewBatchedLoader(channelNameBatch, dataloader.WithWait(time.Millisecond)), |
|
|
}, |
|
|
}, |
|
|
|
|
|
primedKeys: make(map[string]map[string]bool), |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -47,3 +52,29 @@ func (loader *Loader) ToContext(ctx context.Context) context.Context { |
|
|
loader.ctx = ctx |
|
|
loader.ctx = ctx |
|
|
return context.WithValue(ctx, &contextKey, loader) |
|
|
return context.WithValue(ctx, &contextKey, loader) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (loader *Loader) prime(key string, values []string) { |
|
|
|
|
|
loader.mutex.Lock() |
|
|
|
|
|
if loader.primedKeys[key] == nil { |
|
|
|
|
|
loader.primedKeys[key] = make(map[string]bool) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for _, value := range values { |
|
|
|
|
|
loader.primedKeys[key][value] = true |
|
|
|
|
|
} |
|
|
|
|
|
loader.mutex.Unlock() |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (loader *Loader) loadPrimed(key string) { |
|
|
|
|
|
loader.mutex.Lock() |
|
|
|
|
|
if len(loader.primedKeys[key]) > 0 { |
|
|
|
|
|
primedKeys := make([]string, 0, len(loader.primedKeys[key])) |
|
|
|
|
|
for key := range loader.primedKeys[key] { |
|
|
|
|
|
primedKeys = append(primedKeys, key) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
loader.loaders[key].LoadMany(loader.ctx, dataloader.NewKeysFromStrings(primedKeys)) |
|
|
|
|
|
loader.primedKeys[key] = nil |
|
|
|
|
|
} |
|
|
|
|
|
loader.mutex.Unlock() |
|
|
|
|
|
} |