client.go | 16 ++++++++++++++-- data/blob/store.go | 4 ++++ diff --git a/client.go b/client.go index 7ff99428933e2d4ddb1a2d1822be290fe8c98377..d506f5f18bfdfd1111282419afd9875a32b54368 100644 --- a/client.go +++ b/client.go @@ -280,8 +280,20 @@ } if len(p) == 0 { panic(len(p)) } - cl.prepareRead(t, off) - return dataReadAt(t.data, p, off) + // TODO: ReadAt should always try to fill the buffer. + for { + avail := cl.prepareRead(t, off) + if avail < int64(len(p)) { + p = p[:avail] + } + n, err = dataReadAt(t.data, p, off) + if n != 0 || err != io.ErrUnexpectedEOF { + break + } + // If we reach here, the data we thought was ready, isn't. So we + // prepare it again, and retry. + } + return } // Sets priorities to download from the given offset. Returns when the piece diff --git a/data/blob/store.go b/data/blob/store.go index c69886e7820b90ae024ee2c8e77200bd6819b71a..6bb411e4b433ea6f723147481e01365e1bc05937 100644 --- a/data/blob/store.go +++ b/data/blob/store.go @@ -124,6 +124,10 @@ } if !os.IsNotExist(err) { panic(err) } + // Ermahgerd, self heal. This occurs when the underlying data goes + // missing, likely due to a "cache flush", also known as deleting the + // files. TODO: Trigger an asynchronous initCompleted. + delete(me.completed, sliceToPieceHashArray(p.Hash())) f, err = os.Open(me.path(p, false)) if err == nil { return