mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-23 03:34:01 -04:00
fix(core): prevent clipboard & wellbeing data loss from concurrent sessions
Port 2.0
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
_ "golang.org/x/image/webp"
|
||||
|
||||
bolt "go.etcd.io/bbolt"
|
||||
berrors "go.etcd.io/bbolt/errors"
|
||||
|
||||
wlclient "github.com/duxlabs-dev/dux-go/wayland/client"
|
||||
"github.com/duxlabs-dev/dux-go/wayland/ext_data_control"
|
||||
@@ -55,8 +56,14 @@ func NewManager(wlCtx wlcontext.WaylandContext, config Config) (*Manager, error)
|
||||
|
||||
configPath, _ := getConfigPath()
|
||||
|
||||
db, err := openDB(dbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open db: %w", err)
|
||||
}
|
||||
|
||||
m := &Manager{
|
||||
config: config,
|
||||
db: db,
|
||||
configPath: configPath,
|
||||
display: display,
|
||||
wlCtx: wlCtx,
|
||||
@@ -69,6 +76,7 @@ func NewManager(wlCtx wlcontext.WaylandContext, config Config) (*Manager, error)
|
||||
|
||||
if !config.Disabled {
|
||||
if err := m.setupRegistry(); err != nil {
|
||||
db.Close()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -78,12 +86,6 @@ func NewManager(wlCtx wlcontext.WaylandContext, config Config) (*Manager, error)
|
||||
|
||||
go m.watchConfig()
|
||||
|
||||
db, err := openDB(dbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open db: %w", err)
|
||||
}
|
||||
m.db = db
|
||||
|
||||
if err := m.migrateHashes(); err != nil {
|
||||
log.Errorf("Failed to migrate hashes: %v", err)
|
||||
}
|
||||
@@ -117,6 +119,9 @@ func openDB(path string) (*bolt.DB, error) {
|
||||
if err == nil {
|
||||
return db, nil
|
||||
}
|
||||
if errors.Is(err, berrors.ErrTimeout) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Errorf("Clipboard db corrupted, salvaging readable entries: %v", err)
|
||||
|
||||
|
||||
@@ -887,6 +887,24 @@ func TestOpenDB_HealsGarbageFile(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestOpenDB_LockedByAnotherProcessKeepsHistory(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "db")
|
||||
holder, err := openDB(path)
|
||||
require.NoError(t, err)
|
||||
m := &Manager{config: DefaultConfig(), db: holder, dbPath: path}
|
||||
require.NoError(t, m.storeEntry(Entry{Data: []byte("x"), MimeType: "text/plain"}))
|
||||
|
||||
_, err = openDB(path)
|
||||
require.Error(t, err)
|
||||
require.NoError(t, holder.Close())
|
||||
|
||||
reopened, err := openDB(path)
|
||||
require.NoError(t, err)
|
||||
defer reopened.Close()
|
||||
m = &Manager{config: DefaultConfig(), db: reopened, dbPath: path}
|
||||
assert.Len(t, m.GetHistory(), 1)
|
||||
}
|
||||
|
||||
func TestStoreEntry_CorruptDBReturnsErrorNotPanic(t *testing.T) {
|
||||
for _, tt := range corruptDBCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
@@ -194,3 +194,24 @@ func TestAlertRecordSurvivesRestart(t *testing.T) {
|
||||
assert.Nil(t, s.Limit, "the alert already fired before the restart")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenDBLockedByAnotherProcessKeepsData(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "db")
|
||||
c := &clock{now: time.Date(2026, 10, 1, 12, 0, 0, 0, time.UTC)}
|
||||
now := func() time.Time { return c.now }
|
||||
|
||||
m, err := newManager(path, now)
|
||||
require.NoError(t, err)
|
||||
m.SetState("firefox", true, 1)
|
||||
c.advance(10 * time.Second)
|
||||
m.Flush()
|
||||
|
||||
_, err = newManager(path, now)
|
||||
require.Error(t, err)
|
||||
m.Close()
|
||||
|
||||
m, err = newManager(path, now)
|
||||
require.NoError(t, err)
|
||||
defer m.Close()
|
||||
assert.Equal(t, int64(10), m.Summary(1)[0].Active)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package wellbeing
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"github.com/duxlabs-dev/dux-shell/core/internal/log"
|
||||
"github.com/duxlabs-dev/dux-shell/core/internal/utils"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
berrors "go.etcd.io/bbolt/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -31,6 +33,9 @@ func openDB(path string) (*bolt.DB, error) {
|
||||
if err == nil {
|
||||
return db, nil
|
||||
}
|
||||
if errors.Is(err, berrors.ErrTimeout) {
|
||||
return nil, err
|
||||
}
|
||||
log.Errorf("Wellbeing db unreadable, starting over: %v", err)
|
||||
corruptPath := path + ".corrupt"
|
||||
os.Remove(corruptPath)
|
||||
|
||||
Reference in New Issue
Block a user