leveldb: DB.rotateMem: retry DB.newMem three times before panicking #167
diff --git a/leveldb/db_state.go b/leveldb/db_state.go
index 85b02d2..65e1c54 100644
--- a/leveldb/db_state.go
+++ b/leveldb/db_state.go
@@ -7,6 +7,7 @@
package leveldb
import (
+ "errors"
"sync/atomic"
"time"
@@ -15,6 +16,10 @@
"github.com/syndtr/goleveldb/leveldb/storage"
)
+var (
+ errHasFrozenMem = errors.New("has frozen mem")
+)
+
type memDB struct {
db *DB
*memdb.DB
@@ -126,7 +131,7 @@
defer db.memMu.Unlock()
if db.frozenMem != nil {
- panic("still has frozen mem")
+ return nil, errHasFrozenMem
}
if db.journal == nil {
diff --git a/leveldb/db_write.go b/leveldb/db_write.go
index cc428b6..5b6cb48 100644
--- a/leveldb/db_write.go
+++ b/leveldb/db_write.go
@@ -32,15 +32,24 @@
}
func (db *DB) rotateMem(n int, wait bool) (mem *memDB, err error) {
+ retryLimit := 3
+retry:
// Wait for pending memdb compaction.
err = db.compTriggerWait(db.mcompCmdC)
if err != nil {
return
}
+ retryLimit--
// Create new memdb and journal.
mem, err = db.newMem(n)
if err != nil {
+ if err == errHasFrozenMem {
+ if retryLimit <= 0 {
+ panic("BUG: still has frozen memdb")
+ }
+ goto retry
+ }
return
}