From ac8cb98f9709bd70316a88b4e959dcdafeb849cd Mon Sep 17 00:00:00 2001 From: Derek Date: Wed, 3 Jul 2019 19:10:23 -0600 Subject: [PATCH 1/2] Add `LoadOne` func to load 1 request instead of batching --- dataloader/dataloader.go | 1 + dataloader/loader.go | 34 ++++++++++++++++++++++++++++++++++ router/context.go | 1 + 3 files changed, 36 insertions(+) diff --git a/dataloader/dataloader.go b/dataloader/dataloader.go index 98494ae..fea8cf4 100644 --- a/dataloader/dataloader.go +++ b/dataloader/dataloader.go @@ -28,6 +28,7 @@ type DataLoaders interface { // DataLoader interface type DataLoader interface { Load(context.Context, interface{}) (interface{}, error) + LoadOne(context.Context, interface{}) (interface{}, error) LoadMany(context.Context, []interface{}) ([]interface{}, []error) Clear(interface{}) ClearAll() diff --git a/dataloader/loader.go b/dataloader/loader.go index cbf87b5..983ca76 100644 --- a/dataloader/loader.go +++ b/dataloader/loader.go @@ -150,6 +150,40 @@ func (l *Loader) Load(ctx context.Context, key interface{}) (interface{}, error) return thunk() } +// LoadOne loads the given key, doing one request instead of batch, and returns a thunk that resolves the key. +func (l *Loader) LoadOne(ctx context.Context, key interface{}) (interface{}, error) { + c := make(chan Result, 1) + // set batch capacity to 1 + l.batchCap = 1 + + data, err := l.Load(ctx, key) + c <- &Return{data, err} + + var result struct { + mu sync.RWMutex + value Result + } + + thunk := func() (interface{}, error) { + result.mu.RLock() + resultNotSet := result.value == nil + result.mu.RUnlock() + + if resultNotSet { + result.mu.Lock() + if v, ok := <-c; ok { + result.value = v + } + result.mu.Unlock() + } + result.mu.RLock() + defer result.mu.RUnlock() + return result.value.Data(), result.value.Error() + } + + return thunk() +} + // LoadMany loads mulitiple keys, returning a thunk (type: ThunkMany) that will resolve the keys passed in. func (l *Loader) LoadMany(ctx context.Context, keys []interface{}) ([]interface{}, []error) { length := len(keys) diff --git a/router/context.go b/router/context.go index 420b1f8..a8b2a4c 100644 --- a/router/context.go +++ b/router/context.go @@ -123,6 +123,7 @@ type GQLSubscriptionAdaptor interface { // DataLoaderAdaptor interface type DataLoaderAdaptor interface { Load(context.Context, interface{}) (interface{}, error) + LoadOne(context.Context, interface{}) (interface{}, error) LoadMany(context.Context, []interface{}) ([]interface{}, []error) Clear(interface{}) ClearAll() From f0c3d8113922104ca479b11099ab3f2c7839dd7a Mon Sep 17 00:00:00 2001 From: Derek Date: Mon, 8 Jul 2019 21:54:53 -0600 Subject: [PATCH 2/2] Remove redundant code --- dataloader/loader.go | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/dataloader/loader.go b/dataloader/loader.go index 983ca76..9d926db 100644 --- a/dataloader/loader.go +++ b/dataloader/loader.go @@ -152,36 +152,9 @@ func (l *Loader) Load(ctx context.Context, key interface{}) (interface{}, error) // LoadOne loads the given key, doing one request instead of batch, and returns a thunk that resolves the key. func (l *Loader) LoadOne(ctx context.Context, key interface{}) (interface{}, error) { - c := make(chan Result, 1) // set batch capacity to 1 l.batchCap = 1 - - data, err := l.Load(ctx, key) - c <- &Return{data, err} - - var result struct { - mu sync.RWMutex - value Result - } - - thunk := func() (interface{}, error) { - result.mu.RLock() - resultNotSet := result.value == nil - result.mu.RUnlock() - - if resultNotSet { - result.mu.Lock() - if v, ok := <-c; ok { - result.value = v - } - result.mu.Unlock() - } - result.mu.RLock() - defer result.mu.RUnlock() - return result.value.Data(), result.value.Error() - } - - return thunk() + return l.Load(ctx, key) } // LoadMany loads mulitiple keys, returning a thunk (type: ThunkMany) that will resolve the keys passed in.