Fix #277: Periodically write config file while app is running
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend/util"
|
"github.com/dweymouth/supersonic/backend/util"
|
||||||
@@ -50,6 +51,8 @@ type App struct {
|
|||||||
isFirstLaunch bool // set by config file reader
|
isFirstLaunch bool // set by config file reader
|
||||||
bgrndCtx context.Context
|
bgrndCtx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
|
|
||||||
|
lastWrittenCfg Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) VersionTag() string {
|
func (a *App) VersionTag() string {
|
||||||
@@ -80,6 +83,7 @@ func StartupApp(appName, displayAppName, appVersionTag, configFile, latestReleas
|
|||||||
a := &App{appName: appName, appVersionTag: appVersionTag, configFile: configFile}
|
a := &App{appName: appName, appVersionTag: appVersionTag, configFile: configFile}
|
||||||
a.bgrndCtx, a.cancel = context.WithCancel(context.Background())
|
a.bgrndCtx, a.cancel = context.WithCancel(context.Background())
|
||||||
a.readConfig()
|
a.readConfig()
|
||||||
|
a.startConfigWriter(a.bgrndCtx)
|
||||||
|
|
||||||
if !a.Config.Application.AllowMultiInstance {
|
if !a.Config.Application.AllowMultiInstance {
|
||||||
log.Println("Creating session lock file")
|
log.Println("Creating session lock file")
|
||||||
@@ -166,6 +170,23 @@ func (a *App) startSessionWatcher(sessionPath string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// periodically save config file so abnormal exit won't lose settings
|
||||||
|
func (a *App) startConfigWriter(ctx context.Context) {
|
||||||
|
tick := time.NewTicker(2 * time.Minute)
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
tick.Stop()
|
||||||
|
return
|
||||||
|
case <-tick.C:
|
||||||
|
if !reflect.DeepEqual(&a.lastWrittenCfg, a.Config) {
|
||||||
|
a.Config.WriteConfigFile(a.configPath())
|
||||||
|
a.lastWrittenCfg = *a.Config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) callOnReactivate() {
|
func (a *App) callOnReactivate() {
|
||||||
if a.OnReactivate != nil {
|
if a.OnReactivate != nil {
|
||||||
a.OnReactivate()
|
a.OnReactivate()
|
||||||
@@ -276,6 +297,11 @@ func (a *App) Shutdown() {
|
|||||||
os.RemoveAll(configdir.LocalConfig(a.appName, sessionDir))
|
os.RemoveAll(configdir.LocalConfig(a.appName, sessionDir))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) SaveConfigFile() {
|
||||||
|
a.Config.WriteConfigFile(a.configPath())
|
||||||
|
a.lastWrittenCfg = *a.Config
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) configPath() string {
|
func (a *App) configPath() string {
|
||||||
return path.Join(configdir.LocalConfig(a.appName), a.configFile)
|
return path.Join(configdir.LocalConfig(a.appName), a.configFile)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package backend
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pelletier/go-toml/v2"
|
"github.com/pelletier/go-toml/v2"
|
||||||
@@ -206,7 +207,14 @@ func ReadConfigFile(filepath, appVersionTag string) (*Config, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var writeLock sync.Mutex
|
||||||
|
|
||||||
func (c *Config) WriteConfigFile(filepath string) error {
|
func (c *Config) WriteConfigFile(filepath string) error {
|
||||||
|
if !writeLock.TryLock() {
|
||||||
|
return nil // another write in progress
|
||||||
|
}
|
||||||
|
defer writeLock.Unlock()
|
||||||
|
|
||||||
b, err := toml.Marshal(c)
|
b, err := toml.Marshal(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -100,11 +100,13 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
|
|||||||
m.ShowWhatsNewDialog()
|
m.ShowWhatsNewDialog()
|
||||||
}
|
}
|
||||||
m.App.Config.Application.LastLaunchedVersion = app.VersionTag()
|
m.App.Config.Application.LastLaunchedVersion = app.VersionTag()
|
||||||
|
m.App.SaveConfigFile()
|
||||||
} else if t := app.UpdateChecker.VersionTagFound(); t != "" && t != app.Config.Application.LastCheckedVersion {
|
} else if t := app.UpdateChecker.VersionTagFound(); t != "" && t != app.Config.Application.LastCheckedVersion {
|
||||||
if t != app.VersionTag() {
|
if t != app.VersionTag() {
|
||||||
m.ShowNewVersionDialog(displayAppName, t)
|
m.ShowNewVersionDialog(displayAppName, t)
|
||||||
}
|
}
|
||||||
m.App.Config.Application.LastCheckedVersion = t
|
m.App.Config.Application.LastCheckedVersion = t
|
||||||
|
m.App.SaveConfigFile()
|
||||||
}
|
}
|
||||||
// register callback for the ongoing periodic update check
|
// register callback for the ongoing periodic update check
|
||||||
m.App.UpdateChecker.OnUpdatedVersionFound = func() {
|
m.App.UpdateChecker.OnUpdatedVersionFound = func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user