electron-settings: Parallel processes can collide during fs calls, resulting in malformed data and/or thrown errors

The main and renderer process run in different threads, so it’s possible for the main and renderer electron-settings instances to collide when accessing the file system if they attempt to read/write the file at the same time. It should be noted that this issue is not unique to any version of electron-settings, nor electron-settings itself—any framework that can run in both processes that interact with the same file on the filesystem can encounter this problem.

This results in JSON.parse errors or, if the user is lucky, electron-settings will spot malformed JSON and reset the settings to fail gracefully, resulting in loss of data.

Possible solutions

  • Save the settings to a cached object and manipulate that instead. Every set or delete issues a throttled request to save the file to disk, so as to make interaction with the file-system far less frequent and decrease likelihood of collisions. Seems to make no difference && race conditions with FSWatchers
  • Suggest using require('electron').remote.require('electron-settings') in the render process to use the main processes’ electron-settings instance.
  • Suggest using electron-settings in only one process, or sparingly in the other.
  • Instead of throwing, just try to read the settings file again.
  • Find a way to ensure that the electron-settings instance is shared between both processes.
  • Find a way to check if the file is in use before attempting to access it.
  • Use IPC in the renderer to ask the main process’ instance to save the file
screen shot 2017-04-04 at 8 05 01 pm

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

That really does make no sense! You explicitly bind it to the Observer here. And you definitely call it with the right context.

@nathanbuchar run electron-mocha with the --debug switch and put a debugger statement in tests/settings.js inside the "watch()" tests - I think our issue might be somewhere in the message passing between the main and renderer process.

Stepping through the breakpoints takes us to: electron-settings/node_modules/electron/dist/Electron.app/Contents/Resources/electron.asar/renderer/api/remote.js

Maybe this is a Chromium / electron bug with keeping context over ipc? Perhaps the context isn’t passed from the main process to the renderer process for some reason?