Skip to content

Commit 5b1a067

Browse files
committed
feat: add context to interfaces
This adds contexts to all the Datastore interfaces. The motivation for this change is for instrumentation, not cancellation, although these can certainly be used in the future for adding cancellation. We default to adding context to everything, even if we don't immediately use it, because we might need them in the future and making this change again is quite painful due to the large number of repos this fans out to. Note that we have not added context to Close() methods, due to it being surprising given that it breaks the io.Closer interface, and many Close() methods are quick and don't do much work. This also disables the fuzz test, because it has a submodule which transitively depends on this module, so it will fail to build until this change is plumbed through go-ds-flatfs.
1 parent ed11f24 commit 5b1a067

24 files changed

+572
-480
lines changed

autobatch/autobatch.go

+29-26
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package autobatch
55

66
import (
7+
"context"
8+
79
ds "github.com/ipfs/go-datastore"
810
dsq "github.com/ipfs/go-datastore/query"
911
)
@@ -34,16 +36,16 @@ func NewAutoBatching(d ds.Batching, size int) *Datastore {
3436
}
3537

3638
// Delete deletes a key/value
37-
func (d *Datastore) Delete(k ds.Key) error {
39+
func (d *Datastore) Delete(ctx context.Context, k ds.Key) error {
3840
d.buffer[k] = op{delete: true}
3941
if len(d.buffer) > d.maxBufferEntries {
40-
return d.Flush()
42+
return d.Flush(ctx)
4143
}
4244
return nil
4345
}
4446

4547
// Get retrieves a value given a key.
46-
func (d *Datastore) Get(k ds.Key) ([]byte, error) {
48+
func (d *Datastore) Get(ctx context.Context, k ds.Key) ([]byte, error) {
4749
o, ok := d.buffer[k]
4850
if ok {
4951
if o.delete {
@@ -52,22 +54,22 @@ func (d *Datastore) Get(k ds.Key) ([]byte, error) {
5254
return o.value, nil
5355
}
5456

55-
return d.child.Get(k)
57+
return d.child.Get(ctx, k)
5658
}
5759

5860
// Put stores a key/value.
59-
func (d *Datastore) Put(k ds.Key, val []byte) error {
61+
func (d *Datastore) Put(ctx context.Context, k ds.Key, val []byte) error {
6062
d.buffer[k] = op{value: val}
6163
if len(d.buffer) > d.maxBufferEntries {
62-
return d.Flush()
64+
return d.Flush(ctx)
6365
}
6466
return nil
6567
}
6668

6769
// Sync flushes all operations on keys at or under the prefix
6870
// from the current batch to the underlying datastore
69-
func (d *Datastore) Sync(prefix ds.Key) error {
70-
b, err := d.child.Batch()
71+
func (d *Datastore) Sync(ctx context.Context, prefix ds.Key) error {
72+
b, err := d.child.Batch(ctx)
7173
if err != nil {
7274
return err
7375
}
@@ -79,9 +81,9 @@ func (d *Datastore) Sync(prefix ds.Key) error {
7981

8082
var err error
8183
if o.delete {
82-
err = b.Delete(k)
84+
err = b.Delete(ctx, k)
8385
} else {
84-
err = b.Put(k, o.value)
86+
err = b.Put(ctx, k, o.value)
8587
}
8688
if err != nil {
8789
return err
@@ -90,22 +92,22 @@ func (d *Datastore) Sync(prefix ds.Key) error {
9092
delete(d.buffer, k)
9193
}
9294

93-
return b.Commit()
95+
return b.Commit(ctx)
9496
}
9597

9698
// Flush flushes the current batch to the underlying datastore.
97-
func (d *Datastore) Flush() error {
98-
b, err := d.child.Batch()
99+
func (d *Datastore) Flush(ctx context.Context) error {
100+
b, err := d.child.Batch(ctx)
99101
if err != nil {
100102
return err
101103
}
102104

103105
for k, o := range d.buffer {
104106
var err error
105107
if o.delete {
106-
err = b.Delete(k)
108+
err = b.Delete(ctx, k)
107109
} else {
108-
err = b.Put(k, o.value)
110+
err = b.Put(ctx, k, o.value)
109111
}
110112
if err != nil {
111113
return err
@@ -114,21 +116,21 @@ func (d *Datastore) Flush() error {
114116
// clear out buffer
115117
d.buffer = make(map[ds.Key]op, d.maxBufferEntries)
116118

117-
return b.Commit()
119+
return b.Commit(ctx)
118120
}
119121

120122
// Has checks if a key is stored.
121-
func (d *Datastore) Has(k ds.Key) (bool, error) {
123+
func (d *Datastore) Has(ctx context.Context, k ds.Key) (bool, error) {
122124
o, ok := d.buffer[k]
123125
if ok {
124126
return !o.delete, nil
125127
}
126128

127-
return d.child.Has(k)
129+
return d.child.Has(ctx, k)
128130
}
129131

130132
// GetSize implements Datastore.GetSize
131-
func (d *Datastore) GetSize(k ds.Key) (int, error) {
133+
func (d *Datastore) GetSize(ctx context.Context, k ds.Key) (int, error) {
132134
o, ok := d.buffer[k]
133135
if ok {
134136
if o.delete {
@@ -137,26 +139,27 @@ func (d *Datastore) GetSize(k ds.Key) (int, error) {
137139
return len(o.value), nil
138140
}
139141

140-
return d.child.GetSize(k)
142+
return d.child.GetSize(ctx, k)
141143
}
142144

143145
// Query performs a query
144-
func (d *Datastore) Query(q dsq.Query) (dsq.Results, error) {
145-
err := d.Flush()
146+
func (d *Datastore) Query(ctx context.Context, q dsq.Query) (dsq.Results, error) {
147+
err := d.Flush(ctx)
146148
if err != nil {
147149
return nil, err
148150
}
149151

150-
return d.child.Query(q)
152+
return d.child.Query(ctx, q)
151153
}
152154

153155
// DiskUsage implements the PersistentDatastore interface.
154-
func (d *Datastore) DiskUsage() (uint64, error) {
155-
return ds.DiskUsage(d.child)
156+
func (d *Datastore) DiskUsage(ctx context.Context) (uint64, error) {
157+
return ds.DiskUsage(ctx, d.child)
156158
}
157159

158160
func (d *Datastore) Close() error {
159-
err1 := d.Flush()
161+
ctx := context.Background()
162+
err1 := d.Flush(ctx)
160163
err2 := d.child.Close()
161164
if err1 != nil {
162165
return err1

autobatch/autobatch_test.go

+28-20
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package autobatch
22

33
import (
44
"bytes"
5+
"context"
56
"fmt"
67
"testing"
78

@@ -14,6 +15,8 @@ func TestAutobatch(t *testing.T) {
1415
}
1516

1617
func TestFlushing(t *testing.T) {
18+
ctx := context.Background()
19+
1720
child := ds.NewMapDatastore()
1821
d := NewAutoBatching(child, 16)
1922

@@ -24,15 +27,15 @@ func TestFlushing(t *testing.T) {
2427
v := []byte("hello world")
2528

2629
for _, k := range keys {
27-
err := d.Put(k, v)
30+
err := d.Put(ctx, k, v)
2831
if err != nil {
2932
t.Fatal(err)
3033
}
3134
}
3235

3336
// Get works normally.
3437
for _, k := range keys {
35-
val, err := d.Get(k)
38+
val, err := d.Get(ctx, k)
3639
if err != nil {
3740
t.Fatal(err)
3841
}
@@ -43,36 +46,36 @@ func TestFlushing(t *testing.T) {
4346
}
4447

4548
// Not flushed
46-
_, err := child.Get(keys[0])
49+
_, err := child.Get(ctx, keys[0])
4750
if err != ds.ErrNotFound {
4851
t.Fatal("shouldnt have found value")
4952
}
5053

5154
// Delete works.
52-
err = d.Delete(keys[14])
55+
err = d.Delete(ctx, keys[14])
5356
if err != nil {
5457
t.Fatal(err)
5558
}
56-
_, err = d.Get(keys[14])
59+
_, err = d.Get(ctx, keys[14])
5760
if err != ds.ErrNotFound {
5861
t.Fatal(err)
5962
}
6063

6164
// Still not flushed
62-
_, err = child.Get(keys[0])
65+
_, err = child.Get(ctx, keys[0])
6366
if err != ds.ErrNotFound {
6467
t.Fatal("shouldnt have found value")
6568
}
6669

6770
// Final put flushes.
68-
err = d.Put(ds.NewKey("test16"), v)
71+
err = d.Put(ctx, ds.NewKey("test16"), v)
6972
if err != nil {
7073
t.Fatal(err)
7174
}
7275

7376
// should be flushed now, try to get keys from child datastore
7477
for _, k := range keys[:14] {
75-
val, err := child.Get(k)
78+
val, err := child.Get(ctx, k)
7679
if err != nil {
7780
t.Fatal(err)
7881
}
@@ -83,18 +86,18 @@ func TestFlushing(t *testing.T) {
8386
}
8487

8588
// Never flushed the deleted key.
86-
_, err = child.Get(keys[14])
89+
_, err = child.Get(ctx, keys[14])
8790
if err != ds.ErrNotFound {
8891
t.Fatal("shouldnt have found value")
8992
}
9093

9194
// Delete doesn't flush
92-
err = d.Delete(keys[0])
95+
err = d.Delete(ctx, keys[0])
9396
if err != nil {
9497
t.Fatal(err)
9598
}
9699

97-
val, err := child.Get(keys[0])
100+
val, err := child.Get(ctx, keys[0])
98101
if err != nil {
99102
t.Fatal(err)
100103
}
@@ -105,22 +108,24 @@ func TestFlushing(t *testing.T) {
105108
}
106109

107110
func TestSync(t *testing.T) {
111+
ctx := context.Background()
112+
108113
child := ds.NewMapDatastore()
109114
d := NewAutoBatching(child, 100)
110115

111116
put := func(key ds.Key) {
112-
if err := d.Put(key, []byte(key.String())); err != nil {
117+
if err := d.Put(ctx, key, []byte(key.String())); err != nil {
113118
t.Fatal(err)
114119
}
115120
}
116121
del := func(key ds.Key) {
117-
if err := d.Delete(key); err != nil {
122+
if err := d.Delete(ctx, key); err != nil {
118123
t.Fatal(err)
119124
}
120125
}
121126

122127
get := func(d ds.Datastore, key ds.Key) {
123-
val, err := d.Get(key)
128+
val, err := d.Get(ctx, key)
124129
if err != nil {
125130
t.Fatal(err)
126131
}
@@ -130,7 +135,7 @@ func TestSync(t *testing.T) {
130135
}
131136
}
132137
invalidGet := func(d ds.Datastore, key ds.Key) {
133-
if _, err := d.Get(key); err != ds.ErrNotFound {
138+
if _, err := d.Get(ctx, key); err != ds.ErrNotFound {
134139
t.Fatal("should not have found value")
135140
}
136141
}
@@ -146,6 +151,9 @@ func TestSync(t *testing.T) {
146151
// For clarity comments are written as if op = Put and undoOp = Delete
147152
func internalSyncTest(t *testing.T, d, child ds.Datastore, op, undoOp func(ds.Key),
148153
checkOp, checkUndoOp func(ds.Datastore, ds.Key)) {
154+
155+
ctx := context.Background()
156+
149157
var keys []ds.Key
150158
keymap := make(map[ds.Key]int)
151159
for i := 0; i < 4; i++ {
@@ -185,7 +193,7 @@ func internalSyncTest(t *testing.T, d, child ds.Datastore, op, undoOp func(ds.Ke
185193
checkUndoOp(child, ds.NewKey("0"))
186194

187195
// Sync the tree "0/*/*"
188-
if err := d.Sync(ds.NewKey("0")); err != nil {
196+
if err := d.Sync(ctx, ds.NewKey("0")); err != nil {
189197
t.Fatal(err)
190198
}
191199

@@ -196,7 +204,7 @@ func internalSyncTest(t *testing.T, d, child ds.Datastore, op, undoOp func(ds.Ke
196204
checkKeyRange(t, keymap, keys, child, [][]string{{"1", "3/1/1"}}, checkUndoOp)
197205

198206
// Sync the tree "1/1/*"
199-
if err := d.Sync(ds.NewKey("1/1")); err != nil {
207+
if err := d.Sync(ctx, ds.NewKey("1/1")); err != nil {
200208
t.Fatal(err)
201209
}
202210

@@ -207,7 +215,7 @@ func internalSyncTest(t *testing.T, d, child ds.Datastore, op, undoOp func(ds.Ke
207215
checkKeyRange(t, keymap, keys, child, [][]string{{"1", "1/0/1"}, {"2", "3/1/1"}}, checkUndoOp)
208216

209217
// Sync the tree "3/1/1"
210-
if err := d.Sync(ds.NewKey("3/1/1")); err != nil {
218+
if err := d.Sync(ctx, ds.NewKey("3/1/1")); err != nil {
211219
t.Fatal(err)
212220
}
213221

@@ -217,7 +225,7 @@ func internalSyncTest(t *testing.T, d, child ds.Datastore, op, undoOp func(ds.Ke
217225
// Verify no other keys were synchronized
218226
checkKeyRange(t, keymap, keys, child, [][]string{{"1", "1/0/1"}, {"2", "3/1/0"}}, checkUndoOp)
219227

220-
if err := d.Sync(ds.Key{}); err != nil {
228+
if err := d.Sync(ctx, ds.Key{}); err != nil {
221229
t.Fatal(err)
222230
}
223231

@@ -231,7 +239,7 @@ func internalSyncTest(t *testing.T, d, child ds.Datastore, op, undoOp func(ds.Ke
231239
op(deletedKey)
232240

233241
// Sync it
234-
if err := d.Sync(deletedKey); err != nil {
242+
if err := d.Sync(ctx, deletedKey); err != nil {
235243
t.Fatal(err)
236244
}
237245

0 commit comments

Comments
 (0)