summaryrefslogtreecommitdiffstats
path: root/modules/nosql/manager_leveldb.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/nosql/manager_leveldb.go')
-rw-r--r--modules/nosql/manager_leveldb.go40
1 files changed, 34 insertions, 6 deletions
diff --git a/modules/nosql/manager_leveldb.go b/modules/nosql/manager_leveldb.go
index de4ef14d7d..d69ae88800 100644
--- a/modules/nosql/manager_leveldb.go
+++ b/modules/nosql/manager_leveldb.go
@@ -7,6 +7,7 @@ package nosql
import (
"fmt"
"path"
+ "runtime/pprof"
"strconv"
"strings"
@@ -50,7 +51,31 @@ func (m *Manager) CloseLevelDB(connection string) error {
}
// GetLevelDB gets a levelDB for a particular connection
-func (m *Manager) GetLevelDB(connection string) (*leveldb.DB, error) {
+func (m *Manager) GetLevelDB(connection string) (db *leveldb.DB, err error) {
+ // Because we want associate any goroutines created by this call to the main nosqldb context we need to
+ // wrap this in a goroutine labelled with the nosqldb context
+ done := make(chan struct{})
+ var recovered interface{}
+ go func() {
+ defer func() {
+ recovered = recover()
+ if recovered != nil {
+ log.Critical("PANIC during GetLevelDB: %v\nStacktrace: %s", recovered, log.Stack(2))
+ }
+ close(done)
+ }()
+ pprof.SetGoroutineLabels(m.ctx)
+
+ db, err = m.getLevelDB(connection)
+ }()
+ <-done
+ if recovered != nil {
+ panic(recovered)
+ }
+ return
+}
+
+func (m *Manager) getLevelDB(connection string) (*leveldb.DB, error) {
// Convert the provided connection description to the common format
uri := ToLevelDBURI(connection)
@@ -168,15 +193,18 @@ func (m *Manager) GetLevelDB(connection string) (*leveldb.DB, error) {
if err != nil {
if !errors.IsCorrupted(err) {
if strings.Contains(err.Error(), "resource temporarily unavailable") {
- return nil, fmt.Errorf("unable to lock level db at %s: %w", dataDir, err)
+ err = fmt.Errorf("unable to lock level db at %s: %w", dataDir, err)
+ return nil, err
}
- return nil, fmt.Errorf("unable to open level db at %s: %w", dataDir, err)
- }
- db.db, err = leveldb.RecoverFile(dataDir, opts)
- if err != nil {
+ err = fmt.Errorf("unable to open level db at %s: %w", dataDir, err)
return nil, err
}
+ db.db, err = leveldb.RecoverFile(dataDir, opts)
+ }
+
+ if err != nil {
+ return nil, err
}
for _, name := range db.name {