Skip to content

Commit

Permalink
Fix #277: Periodically write config file while app is running
Browse files Browse the repository at this point in the history
  • Loading branch information
dweymouth committed Nov 10, 2023
1 parent 68c05dd commit 9f157e0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
26 changes: 26 additions & 0 deletions backend/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log"
"os"
"path"
"reflect"
"time"

"github.com/dweymouth/supersonic/backend/util"
Expand Down Expand Up @@ -50,6 +51,8 @@ type App struct {
isFirstLaunch bool // set by config file reader
bgrndCtx context.Context
cancel context.CancelFunc

lastWrittenCfg Config
}

func (a *App) VersionTag() string {
Expand Down Expand Up @@ -80,6 +83,7 @@ func StartupApp(appName, displayAppName, appVersionTag, configFile, latestReleas
a := &App{appName: appName, appVersionTag: appVersionTag, configFile: configFile}
a.bgrndCtx, a.cancel = context.WithCancel(context.Background())
a.readConfig()
a.startConfigWriter(a.bgrndCtx)

if !a.Config.Application.AllowMultiInstance {
log.Println("Creating session lock file")
Expand Down Expand Up @@ -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() {
if a.OnReactivate != nil {
a.OnReactivate()
Expand Down Expand Up @@ -276,6 +297,11 @@ func (a *App) Shutdown() {
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 {
return path.Join(configdir.LocalConfig(a.appName), a.configFile)
}
Expand Down
8 changes: 8 additions & 0 deletions backend/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package backend

import (
"os"
"sync"

"github.com/google/uuid"
"github.com/pelletier/go-toml/v2"
Expand Down Expand Up @@ -206,7 +207,14 @@ func ReadConfigFile(filepath, appVersionTag string) (*Config, error) {
return c, nil
}

var writeLock sync.Mutex

func (c *Config) WriteConfigFile(filepath string) error {
if !writeLock.TryLock() {
return nil // another write in progress
}
defer writeLock.Unlock()

b, err := toml.Marshal(c)
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions ui/mainwindow.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,13 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
m.ShowWhatsNewDialog()
}
m.App.Config.Application.LastLaunchedVersion = app.VersionTag()
m.App.SaveConfigFile()
} else if t := app.UpdateChecker.VersionTagFound(); t != "" && t != app.Config.Application.LastCheckedVersion {
if t != app.VersionTag() {
m.ShowNewVersionDialog(displayAppName, t)
}
m.App.Config.Application.LastCheckedVersion = t
m.App.SaveConfigFile()
}
// register callback for the ongoing periodic update check
m.App.UpdateChecker.OnUpdatedVersionFound = func() {
Expand Down

0 comments on commit 9f157e0

Please sign in to comment.