Skip to content

Commit 40ecb17

Browse files
committed
refactor: reuse noop span
1 parent ade8833 commit 40ecb17

File tree

3 files changed

+27
-21
lines changed

3 files changed

+27
-21
lines changed

.github/workflows/go.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
strategy:
1414
fail-fast: false
1515
matrix:
16-
version: ["1.21.x", "1.22.x"]
16+
version: ["1.22.x"]
1717
steps:
1818
- uses: actions/checkout@v4
1919

benchmark_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"testing"
7+
"time"
78
)
89

910
func BenchmarkDataLoader(b *testing.B) {
@@ -12,18 +13,23 @@ func BenchmarkDataLoader(b *testing.B) {
1213
for i, key := range keys {
1314
results[i] = Result[string]{data: fmt.Sprintf("Result for %d", key)}
1415
}
16+
time.Sleep(1 * time.Millisecond)
1517
return results
1618
}
1719

18-
loader := New(batchFunc)
20+
loader := New(batchFunc, WithBatchSize(10))
1921

2022
b.Run("direct.Batch", func(b *testing.B) {
23+
b.ResetTimer()
2124
for i := 0; i < b.N; i++ {
2225
_ = batchFunc(context.Background(), []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
2326
}
2427
})
2528

2629
b.Run("dataloader.Load", func(b *testing.B) {
30+
loader.ClearAll()
31+
b.ResetTimer()
32+
2733
for i := 0; i < b.N; i++ {
2834
for j := 0; j < 10; j++ {
2935
_ = loader.Load(context.Background(), j)
@@ -32,12 +38,18 @@ func BenchmarkDataLoader(b *testing.B) {
3238
})
3339

3440
b.Run("dataloader.LoadMany", func(b *testing.B) {
41+
loader.ClearAll()
42+
b.ResetTimer()
43+
3544
for i := 0; i < b.N; i++ {
3645
_ = loader.LoadMany(context.Background(), []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
3746
}
3847
})
3948

4049
b.Run("dataloader.LoadMap", func(b *testing.B) {
50+
loader.ClearAll()
51+
b.ResetTimer()
52+
4153
for i := 0; i < b.N; i++ {
4254
_ = loader.LoadMap(context.Background(), []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
4355
}

dataloader.go

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,7 @@ import (
1313
"go.opentelemetry.io/otel/trace/noop"
1414
)
1515

16-
// Loader is the function type for loading data
17-
type Loader[K comparable, V any] func(context.Context, []K) []Result[V]
18-
19-
// Interface is a `DataLoader` Interface which defines a public API for loading data from a particular
20-
// data back-end with unique keys such as the `id` column of a SQL table or
21-
// document name in a MongoDB database, given a batch loading function.
16+
// Interface defines a public API for loading data from a particular data source
2217
type Interface[K comparable, V any] interface {
2318
// Load loads a single key
2419
Load(context.Context, K) Result[V]
@@ -34,6 +29,9 @@ type Interface[K comparable, V any] interface {
3429
Prime(ctx context.Context, key K, value V) Interface[K, V]
3530
}
3631

32+
// Loader is the function type for loading data
33+
type Loader[K comparable, V any] func(context.Context, []K) []Result[V]
34+
3735
// config holds the configuration for DataLoader
3836
type config struct {
3937
// BatchSize is the number of keys to batch together, Default is 100
@@ -68,7 +66,6 @@ func New[K comparable, V any](loader Loader[K, V], options ...Option) Interface[
6866
CacheSize: 1024,
6967
CacheExpire: time.Minute,
7068
}
71-
7269
for _, option := range options {
7370
option(&config)
7471
}
@@ -79,12 +76,10 @@ func New[K comparable, V any](loader Loader[K, V], options ...Option) Interface[
7976
stopSchedule: make(chan struct{}),
8077
}
8178
dl.reset()
82-
8379
// Create a cache if the cache size is greater than 0
8480
if config.CacheSize > 0 {
8581
dl.cache = expirable.NewLRU[K, V](config.CacheSize, nil, config.CacheExpire)
8682
}
87-
8883
return dl
8984
}
9085

@@ -197,7 +192,6 @@ func (d *dataLoader[K, V]) goLoad(ctx context.Context, key K) <-chan Result[V] {
197192
// spawn a new goroutine to process the batch
198193
go d.processBatch(ctx, d.batch, d.batchCtx, d.chs)
199194
close(d.stopSchedule)
200-
// Create a new batch, and a new set of channels
201195
d.reset()
202196
}
203197

@@ -225,14 +219,13 @@ func (d *dataLoader[K, V]) scheduleBatch(ctx context.Context, stopSchedule <-cha
225219
func (d *dataLoader[K, V]) processBatch(ctx context.Context, keys []K, batchCtx []context.Context, chs map[K][]chan Result[V]) {
226220
defer func() {
227221
if r := recover(); r != nil {
228-
const size = 64 << 10
229-
buf := make([]byte, size)
222+
buf := make([]byte, 64<<10)
230223
buf = buf[:runtime.Stack(buf, false)]
231224
err := fmt.Errorf("dataloader: panic received in loader function: %v", r)
232225
fmt.Fprintf(os.Stderr, "%v\n%s", err, buf)
233226

234227
for _, chs := range chs {
235-
sendResult(chs, Result[V]{err: err})
228+
d.sendResult(chs, Result[V]{err: err})
236229
}
237230
}
238231
}()
@@ -259,32 +252,33 @@ func (d *dataLoader[K, V]) processBatch(ctx context.Context, keys []K, batchCtx
259252
if results[i].err == nil && d.cache != nil {
260253
d.cache.Add(key, results[i].data)
261254
}
262-
sendResult(chs[key], results[i])
255+
d.sendResult(chs[key], results[i])
263256
}
264257
}
265258

266-
// reset resets the DataLoader
259+
// reset resets the DataLoader state
267260
func (d *dataLoader[K, V]) reset() {
268261
d.batch = make([]K, 0, d.config.BatchSize)
269262
d.batchCtx = make([]context.Context, 0, d.config.BatchSize)
270263
d.chs = make(map[K][]chan Result[V], d.config.BatchSize)
271264
}
272265

273266
// sendResult sends a result to channels
274-
func sendResult[V any](chs []chan Result[V], result Result[V]) {
267+
func (d *dataLoader[K, V]) sendResult(chs []chan Result[V], result Result[V]) {
275268
for _, ch := range chs {
276269
ch <- result
277270
close(ch)
278271
}
279272
}
280273

274+
var noopSpan = noop.Span{}
275+
281276
// startTrace starts a trace span
282277
func (d *dataLoader[K, V]) startTrace(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
283278
if d.config.TracerProvider != nil {
284-
span := trace.SpanFromContext(ctx)
285-
if span.SpanContext().IsValid() {
279+
if span := trace.SpanFromContext(ctx); span.SpanContext().IsValid() {
286280
return d.config.TracerProvider.Tracer("dataLoader").Start(ctx, name, opts...)
287281
}
288282
}
289-
return ctx, noop.Span{}
283+
return ctx, noopSpan
290284
}

0 commit comments

Comments
 (0)