Skip to content

Commit 9f529bc

Browse files
committed
remove ThreadSafeDatastore
It's a lie! We: 1. Assume that our datastores are thread-safe all over the place, not bothering to check for this interface. 2. Implement this interface for, e.g., the mount datastore that _may not_ be thread-safe (depending on the sub-datastores). Basically, there's no sane way to to do something like this in go. What we _want_ is: ```rust pub trait ThreadSafe {} struct MyWrapper<D: Datastore> { ... } impl<D: Datastore> ThreadSafe for MyWrapper<D> where D: ThreadSafe {} ``` Actually, we don't even need this because rust has already done all the hard work with the `Sync` trait. .... But we're using go which barely has types. --- For completeness, it's actually possible to do this in go: ```go type threadSafeMixin struct{} func (threadSafeMixin) ThreadSafe() {} func NewWrapper(d Datastore) Datastore { if _, ok := d.(ThreadSafe) { return &struct{myWrapper, threadSafeMixin}{myWrapper{d}, threadSafeMixin{}} } return &myWrapper{d} } ``` Let's not.
1 parent 1b37198 commit 9f529bc

File tree

4 files changed

+5
-16
lines changed

4 files changed

+5
-16
lines changed

basic_ds.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ type MapDatastore struct {
1313
values map[Key][]byte
1414
}
1515

16-
// NewMapDatastore constructs a MapDatastore
16+
// NewMapDatastore constructs a MapDatastore. It is _not_ thread-safe by
17+
// default, wrap using sync.MutexWrap if you need thread safety (the answer here
18+
// is usually yes).
1719
func NewMapDatastore() (d *MapDatastore) {
1820
return &MapDatastore{
1921
values: make(map[Key][]byte),

datastore.go

-8
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,6 @@ type Batching interface {
102102
// actually support batching.
103103
var ErrBatchUnsupported = errors.New("this datastore does not support batching")
104104

105-
// ThreadSafeDatastore is an interface that all threadsafe datastore should
106-
// implement to leverage type safety checks.
107-
type ThreadSafeDatastore interface {
108-
Datastore
109-
110-
IsThreadSafe()
111-
}
112-
113105
// CheckedDatastore is an interface that should be implemented by datastores
114106
// which may need checking on-disk data integrity.
115107
type CheckedDatastore interface {

mount/mount.go

-2
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,6 @@ func (d *Datastore) Query(q query.Query) (query.Results, error) {
190190
}), nil
191191
}
192192

193-
func (d *Datastore) IsThreadSafe() {}
194-
195193
func (d *Datastore) Close() error {
196194
for _, d := range d.mounts {
197195
err := d.Datastore.Close()

sync/sync.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ type MutexDatastore struct {
1515
child ds.Datastore
1616
}
1717

18-
// MutexWrap constructs a datastore with a coarse lock around
19-
// the entire datastore, for every single operation
18+
// MutexWrap constructs a datastore with a coarse lock around the entire
19+
// datastore, for every single operation.
2020
func MutexWrap(d ds.Datastore) *MutexDatastore {
2121
return &MutexDatastore{child: d}
2222
}
@@ -26,9 +26,6 @@ func (d *MutexDatastore) Children() []ds.Datastore {
2626
return []ds.Datastore{d.child}
2727
}
2828

29-
// IsThreadSafe implements ThreadSafeDatastore
30-
func (d *MutexDatastore) IsThreadSafe() {}
31-
3229
// Put implements Datastore.Put
3330
func (d *MutexDatastore) Put(key ds.Key, value []byte) (err error) {
3431
d.Lock()

0 commit comments

Comments
 (0)