Skip to content

Commit 7813937

Browse files
author
Nick Randall
committed
Implement Key interface for V5
1 parent 21af3a9 commit 7813937

File tree

11 files changed

+258
-180
lines changed

11 files changed

+258
-180
lines changed

README.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This is an implementation of [Facebook's DataLoader](https://github.com/facebook
99
This project is a work in progress. Feedback is encouraged.
1010

1111
## Install
12-
`go get -u gopkg.in/nicksrandall/dataloader.v4`
12+
`go get -u gopkg.in/nicksrandall/dataloader.v5`
1313

1414
## Usage
1515
```go
@@ -103,6 +103,32 @@ type Cache interface {
103103
}
104104
```
105105

106+
## Upgrade from v4 to v5
107+
```diff
108+
// dataloader.Interface as now allows interace{} as key rather than string
109+
- loader.Load(context.Context, key interface{}) Thunk
110+
+ loader.Load(ctx context.Context, key Key) Thunk
111+
- loader.LoadMany(context.Context, key []interface{}) ThunkMany
112+
+ loader.LoadMany(ctx context.Context, keys Keys) ThunkMany
113+
- loader.Prime(context.Context, key interface{}, value interface{}) Interface
114+
+ loader.Prime(ctx context.Context, key Key, value interface{}) Interface
115+
- loader.Clear(context.Context, key interface{}) Interface
116+
+ loader.Clear(ctx context.Context, key Key) Interface
117+
```
118+
119+
```diff
120+
// cache interface now allows interface{} as key instead of string
121+
type Cache interface {
122+
- Get(context.Context, interface{}) (Thunk, bool)
123+
+ Get(context.Context, Key) (Thunk, bool)
124+
- Set(context.Context, interface{}, Thunk)
125+
+ Set(context.Context, Key, Thunk)
126+
- Delete(context.Context, interface{}) bool
127+
+ Delete(context.Context, Key) bool
128+
Clear()
129+
}
130+
```
131+
106132
### Don't need/want to use context?
107133
You're welcome to install the v1 version of this library.
108134

cache.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import "context"
44

55
// The Cache interface. If a custom cache is provided, it must implement this interface.
66
type Cache interface {
7-
Get(context.Context, interface{}) (Thunk, bool)
8-
Set(context.Context, interface{}, Thunk)
9-
Delete(context.Context, interface{}) bool
7+
Get(context.Context, Key) (Thunk, bool)
8+
Set(context.Context, Key, Thunk)
9+
Delete(context.Context, Key) bool
1010
Clear()
1111
}
1212

@@ -16,13 +16,13 @@ type Cache interface {
1616
type NoCache struct{}
1717

1818
// Get is a NOOP
19-
func (c *NoCache) Get(context.Context, interface{}) (Thunk, bool) { return nil, false }
19+
func (c *NoCache) Get(context.Context, Key) (Thunk, bool) { return nil, false }
2020

2121
// Set is a NOOP
22-
func (c *NoCache) Set(context.Context, interface{}, Thunk) { return }
22+
func (c *NoCache) Set(context.Context, Key, Thunk) { return }
2323

2424
// Delete is a NOOP
25-
func (c *NoCache) Delete(context.Context, interface{}) bool { return false }
25+
func (c *NoCache) Delete(context.Context, Key) bool { return false }
2626

2727
// Clear is a NOOP
2828
func (c *NoCache) Clear() { return }

dataloader.go

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ import (
2020
// different access permissions and consider creating a new instance per
2121
// web request.
2222
type Interface interface {
23-
Load(context.Context, interface{}) Thunk
24-
LoadMany(context.Context, []interface{}) ThunkMany
25-
Clear(context.Context, string) Interface
23+
Load(context.Context, Key) Thunk
24+
LoadMany(context.Context, Keys) ThunkMany
25+
Clear(context.Context, Key) Interface
2626
ClearAll() Interface
27-
Prime(ctx context.Context, key interface{}, value interface{}) Interface
27+
Prime(ctx context.Context, key Key, value interface{}) Interface
2828
}
2929

3030
// BatchFunc is a function, which when given a slice of keys (string), returns an slice of `results`.
3131
// It's important that the length of the input keys matches the length of the output results.
3232
//
3333
// The keys passed to this function are guaranteed to be unique
34-
type BatchFunc func(context.Context, []interface{}) []*Result
34+
type BatchFunc func(context.Context, Keys) []*Result
3535

3636
// Result is the data structure that a BatchFunc returns.
3737
// It contains the resolved data, and any errors that may have occurred while fetching the data.
@@ -100,7 +100,7 @@ type ThunkMany func() ([]interface{}, []error)
100100

101101
// type used to on input channel
102102
type batchRequest struct {
103-
key interface{}
103+
key Key
104104
channel chan *Result
105105
}
106106

@@ -191,7 +191,7 @@ func NewBatchedLoader(batchFn BatchFunc, opts ...Option) *Loader {
191191
}
192192

193193
// Load load/resolves the given key, returning a channel that will contain the value and error
194-
func (l *Loader) Load(originalContext context.Context, key interface{}) Thunk {
194+
func (l *Loader) Load(originalContext context.Context, key Key) Thunk {
195195
ctx, finish := l.tracer.TraceLoad(originalContext, key)
196196

197197
c := make(chan *Result, 1)
@@ -267,7 +267,7 @@ func (l *Loader) Load(originalContext context.Context, key interface{}) Thunk {
267267
}
268268

269269
// LoadMany loads mulitiple keys, returning a thunk (type: ThunkMany) that will resolve the keys passed in.
270-
func (l *Loader) LoadMany(originalContext context.Context, keys []interface{}) ThunkMany {
270+
func (l *Loader) LoadMany(originalContext context.Context, keys Keys) ThunkMany {
271271
ctx, finish := l.tracer.TraceLoadMany(originalContext, keys)
272272

273273
var (
@@ -278,15 +278,17 @@ func (l *Loader) LoadMany(originalContext context.Context, keys []interface{}) T
278278
wg sync.WaitGroup
279279
)
280280

281+
resolve := func(ctx context.Context, i int) {
282+
defer wg.Done()
283+
thunk := l.Load(ctx, keys[i])
284+
result, err := thunk()
285+
data[i] = result
286+
errors[i] = err
287+
}
288+
281289
wg.Add(length)
282290
for i := range keys {
283-
go func(ctx context.Context, i int) {
284-
defer wg.Done()
285-
thunk := l.Load(ctx, keys[i])
286-
result, err := thunk()
287-
data[i] = result
288-
errors[i] = err
289-
}(ctx, i)
291+
go resolve(ctx, i)
290292
}
291293

292294
go func() {
@@ -333,7 +335,7 @@ func (l *Loader) LoadMany(originalContext context.Context, keys []interface{}) T
333335
}
334336

335337
// Clear clears the value at `key` from the cache, it it exsits. Returs self for method chaining
336-
func (l *Loader) Clear(ctx context.Context, key string) Interface {
338+
func (l *Loader) Clear(ctx context.Context, key Key) Interface {
337339
l.cacheLock.Lock()
338340
l.cache.Delete(ctx, key)
339341
l.cacheLock.Unlock()
@@ -351,7 +353,7 @@ func (l *Loader) ClearAll() Interface {
351353

352354
// Prime adds the provided key and value to the cache. If the key already exists, no change is made.
353355
// Returns self for method chaining
354-
func (l *Loader) Prime(ctx context.Context, key interface{}, value interface{}) Interface {
356+
func (l *Loader) Prime(ctx context.Context, key Key, value interface{}) Interface {
355357
if _, ok := l.cache.Get(ctx, key); !ok {
356358
thunk := func() (interface{}, error) {
357359
return value, nil
@@ -399,10 +401,12 @@ func (b *batcher) end() {
399401

400402
// execute the batch of all items in queue
401403
func (b *batcher) batch(originalContext context.Context) {
402-
var keys []interface{}
403-
var reqs []*batchRequest
404-
var items []*Result
405-
var panicErr interface{}
404+
var (
405+
keys = make(Keys, 0)
406+
reqs = make([]*batchRequest, 0)
407+
items = make([]*Result, 0)
408+
panicErr interface{}
409+
)
406410

407411
for item := range b.input {
408412
keys = append(keys, item.key)

0 commit comments

Comments
 (0)