From 466257d3bedfa25663804061bdfc3933accb5df0 Mon Sep 17 00:00:00 2001 From: Sergey Stepanov Date: Wed, 7 Aug 2024 20:20:21 +0300 Subject: [PATCH] Add NonBlockingSave option for background saving This feature introduces a new configuration option, `NonBlockingSave`, which allows background saving for large files. With this param the saving process will not block the main thread with all network sockets. By default, it's enabled for the DosBox core. --- pkg/config/config.yaml | 2 ++ pkg/config/emulator.go | 1 + pkg/worker/caged/libretro/frontend.go | 1 + pkg/worker/caged/libretro/storage.go | 20 +++++++++++++++----- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pkg/config/config.yaml b/pkg/config/config.yaml index 1f73955a..d00ff5c1 100644 --- a/pkg/config/config.yaml +++ b/pkg/config/config.yaml @@ -192,6 +192,7 @@ emulator: # Some cores allow binding multiple devices to a single port (DosBox), but typically, # you should bind just one device to one port. # - kbMouseSupport (bool) -- (temp) a flag if the core needs the keyboard and mouse on the client + # - nonBlockingSave (bool) -- write save file in a non-blocking way, needed for huge save files # - vfr (bool) # (experimental) # Enable variable frame rate only for cores that can't produce a constant frame rate. @@ -271,6 +272,7 @@ emulator: roms: [ "zip", "cue" ] folder: dos kbMouseSupport: true + nonBlockingSave: true hid: 0: [ 257, 513 ] 1: [ 257, 513 ] diff --git a/pkg/config/emulator.go b/pkg/config/emulator.go index ddb08ba5..2a25f740 100644 --- a/pkg/config/emulator.go +++ b/pkg/config/emulator.go @@ -50,6 +50,7 @@ type LibretroCoreConfig struct { IsGlAllowed bool KbMouseSupport bool Lib string + NonBlockingSave bool Options map[string]string Options4rom map[string]map[string]string // <(^_^)> Roms []string diff --git a/pkg/worker/caged/libretro/frontend.go b/pkg/worker/caged/libretro/frontend.go index 91b92c1b..a8465488 100644 --- a/pkg/worker/caged/libretro/frontend.go +++ b/pkg/worker/caged/libretro/frontend.go @@ -158,6 +158,7 @@ func (f *Frontend) LoadCore(emu string) { scale = conf.Scale f.log.Debug().Msgf("Scale: x%v", scale) } + f.storage.SetNonBlocking(conf.NonBlockingSave) f.scale = scale f.nano.CoreLoad(meta) f.mu.Unlock() diff --git a/pkg/worker/caged/libretro/storage.go b/pkg/worker/caged/libretro/storage.go index e7c488a0..fc1a5a76 100644 --- a/pkg/worker/caged/libretro/storage.go +++ b/pkg/worker/caged/libretro/storage.go @@ -13,6 +13,7 @@ type ( GetSavePath() string GetSRAMPath() string SetMainSaveName(name string) + SetNonBlocking(v bool) Load(path string) ([]byte, error) Save(path string, data []byte) error } @@ -24,17 +25,26 @@ type ( // needed for Google Cloud save/restore which // doesn't support multiple files MainSave string + NonBlock bool } ZipStorage struct { Storage } ) -func (s *StateStorage) SetMainSaveName(name string) { s.MainSave = name } -func (s *StateStorage) GetSavePath() string { return filepath.Join(s.Path, s.MainSave+".dat") } -func (s *StateStorage) GetSRAMPath() string { return filepath.Join(s.Path, s.MainSave+".srm") } -func (s *StateStorage) Load(path string) ([]byte, error) { return os.ReadFile(path) } -func (s *StateStorage) Save(path string, dat []byte) error { return os.WriteFile(path, dat, 0644) } +func (s *StateStorage) SetMainSaveName(name string) { s.MainSave = name } +func (s *StateStorage) SetNonBlocking(v bool) { s.NonBlock = v } +func (s *StateStorage) GetSavePath() string { return filepath.Join(s.Path, s.MainSave+".dat") } +func (s *StateStorage) GetSRAMPath() string { return filepath.Join(s.Path, s.MainSave+".srm") } +func (s *StateStorage) Load(path string) ([]byte, error) { return os.ReadFile(path) } +func (s *StateStorage) Save(path string, dat []byte) error { + if s.NonBlock { + go func() { _ = os.WriteFile(path, dat, 0644) }() + return nil + } + + return os.WriteFile(path, dat, 0644) +} func (z *ZipStorage) GetSavePath() string { return z.Storage.GetSavePath() + zip.Ext } func (z *ZipStorage) GetSRAMPath() string { return z.Storage.GetSRAMPath() + zip.Ext }