diff options
author | holisticode <holistic.computing@gmail.com> | 2019-02-13 07:17:44 +0800 |
---|---|---|
committer | Rafael Matias <rafael@skyle.net> | 2019-02-19 20:11:51 +0800 |
commit | 7a333e41046e818604f07fcfd6654af30fe70bf9 (patch) | |
tree | 36bc048e088819f04144e64e30525dbe9643ee58 | |
parent | 799fe99537e57f2651c24dcd628f3a2db2fe7ef9 (diff) | |
download | dexon-7a333e41046e818604f07fcfd6654af30fe70bf9.tar dexon-7a333e41046e818604f07fcfd6654af30fe70bf9.tar.gz dexon-7a333e41046e818604f07fcfd6654af30fe70bf9.tar.bz2 dexon-7a333e41046e818604f07fcfd6654af30fe70bf9.tar.lz dexon-7a333e41046e818604f07fcfd6654af30fe70bf9.tar.xz dexon-7a333e41046e818604f07fcfd6654af30fe70bf9.tar.zst dexon-7a333e41046e818604f07fcfd6654af30fe70bf9.zip |
swarm/storage: fix HashExplore concurrency bug ethersphere#1211 (#19028)
* swarm/storage: fix HashExplore concurrency bug ethersphere#1211
* swarm/storage: lock as value not pointer
* swarm/storage: wait for to complete
* swarm/storage: fix linter problems
* swarm/storage: append to nil slice
(cherry picked from commit 3d22a46c94f1d842dbada665b36a453362adda74)
-rw-r--r-- | swarm/storage/filestore.go | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/swarm/storage/filestore.go b/swarm/storage/filestore.go index 4240f5b1c..0bad944ee 100644 --- a/swarm/storage/filestore.go +++ b/swarm/storage/filestore.go @@ -20,6 +20,7 @@ import ( "context" "io" "sort" + "sync" ) /* @@ -101,38 +102,45 @@ func (f *FileStore) HashSize() int { // GetAllReferences is a public API. This endpoint returns all chunk hashes (only) for a given file func (f *FileStore) GetAllReferences(ctx context.Context, data io.Reader, toEncrypt bool) (addrs AddressCollection, err error) { // create a special kind of putter, which only will store the references - putter := &HashExplorer{ + putter := &hashExplorer{ hasherStore: NewHasherStore(f.ChunkStore, f.hashFunc, toEncrypt), - References: make([]Reference, 0), } // do the actual splitting anyway, no way around it - _, _, err = PyramidSplit(ctx, data, putter, putter) + _, wait, err := PyramidSplit(ctx, data, putter, putter) + if err != nil { + return nil, err + } + // wait for splitting to be complete and all chunks processed + err = wait(ctx) if err != nil { return nil, err } // collect all references addrs = NewAddressCollection(0) - for _, ref := range putter.References { + for _, ref := range putter.references { addrs = append(addrs, Address(ref)) } sort.Sort(addrs) return addrs, nil } -// HashExplorer is a special kind of putter which will only store chunk references -type HashExplorer struct { +// hashExplorer is a special kind of putter which will only store chunk references +type hashExplorer struct { *hasherStore - References []Reference + references []Reference + lock sync.Mutex } // HashExplorer's Put will add just the chunk hashes to its `References` -func (he *HashExplorer) Put(ctx context.Context, chunkData ChunkData) (Reference, error) { +func (he *hashExplorer) Put(ctx context.Context, chunkData ChunkData) (Reference, error) { // Need to do the actual Put, which returns the references ref, err := he.hasherStore.Put(ctx, chunkData) if err != nil { return nil, err } // internally store the reference - he.References = append(he.References, ref) + he.lock.Lock() + he.references = append(he.references, ref) + he.lock.Unlock() return ref, nil } |