Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multipe instances of an Electron app have problems with localStorage #2493

Closed
duanyao opened this issue Aug 13, 2015 · 15 comments
Closed

Multipe instances of an Electron app have problems with localStorage #2493

duanyao opened this issue Aug 13, 2015 · 15 comments

Comments

@duanyao
Copy link

duanyao commented Aug 13, 2015

If we start multipe instances of an Electron app, they will have problems with localStorage:

  • One instance can not see the change to the localStorage made by another one during its lifetime.
  • storage event is not fired after another instance made change to the localStorage.
  • If two instances make changes to a same key, the last change win (becomes persistent) after all of them exit.

I think this problem, as well as #2483, make multipe instance mode of electron very dangerous. I think Electron should officially ban multipe instance mode untils these problems are solved, or users' data are in risk.

Tested with 0.30.4-win32 on Win7 64bit.

@deepak1556
Copy link
Member

the situation is two independent browser context operating on same storage partition path, these race conditions are to happen. You need to set a different user data path for the new instance.

@duanyao
Copy link
Author

duanyao commented Aug 13, 2015

@deepak1556 Note that this issue is about multiple instances of a same electron app, so the user data path must be the same for those instances.

@etiktin
Copy link
Contributor

etiktin commented Aug 14, 2015

One possible way to overcome this (while a real solution is being worked on), is to modify your app in the following manner:
When the application loads, it checks if there's another instance. If there isn't it loads the business logic. If there is, it will notify the other instance and exit. The other instance will open a new window for your app so it will appear like you have 2 instances running. The underline assumption here is that the issue doesn't happen in 2 windows generated from the same main process. This way you should be able to bypass the persistency issues, but it will complicate the main process.

Regarding the following:

If two instances make changes to a same key, the last change win (becomes persistent) after all of them exit.

The fact that that the change is written when they exit, is a problem. But the last change wins, isn't (that's exactly how localStorage is designed to work).

@deepak1556
Copy link
Member

@duanyao sorry i suggested it as solution for Electron prohibitng multiple instances, i believe it should be left to app developers if they should allow multiple instances. The limiting factor for these storage api usage in multiple instances is because of the backend they rely on , for one indexdb, file system cant be used as leveldb has this issue . And localstorage is a real racy api (no storage mutex implementation). I am not sure if these can be patched in Electron.

@duanyao
Copy link
Author

duanyao commented Aug 15, 2015

@etiktin

When the application loads, it checks if there's another instance. If there isn't it loads the business logic. If there is, it will notify the other instance and exit. The other instance will open a new window for your app so it will appear like you have 2 instances running.

Yeah, this is what I'm doing now. If this is the only way to safely use localStorage etc. in Electron, shouldn't Electron make it default, or at least provides a API/config option to do so? However in #648, Electron team asked developers to do it themselves, which made me thought that multi-instance mode is safe and supported.

But the last change wins, isn't (that's exactly how localStorage is designed to work).

Yes, but other instances can't see the change and just assumes they have won (imaging a text editor which saves files in localStorage). If Electron can't make localStorage work as expected in multi-instance mode, I think it's better to make localStorage's API throw for following instances.

@duanyao
Copy link
Author

duanyao commented Aug 15, 2015

@deepak1556 Thanks for the explanation. If there are implementation limitation in chomium, I think it is better for Electron to fail nosily when multiple instances are trying to access these storage APIs.

@zcbenz
Copy link
Contributor

zcbenz commented Jan 6, 2016

I'm closing this won't fix, localStorage is simply not designed to be used by two instances together.

@pgupt
Copy link

pgupt commented Feb 5, 2020

My problems is that it is working in development mode but not in production. Why would that be? I am creating a second instance which has localstorage null.

@cata-code
Copy link

If you want information saved across your entire app, you can use a settings.json file.

import { app } from 'electron'
import fs from 'fs'

const file = app.getPath('userData') + '/settings.json'
console.log(file) // see where this file is saved
const settings = { foo: 'bar' }

fs.writeFileSync(file, JSON.stringify(settings, null, 2)) // if file doesn't exist it's created

@bennymeg
Copy link

bennymeg commented Feb 1, 2021

Would IndexedDB will suffer from the same issue?

@joaodforce
Copy link

Would IndexedDB will suffer from the same issue?

I was wondering the same, because I'm facing this exact same issue after I started working with multiple windows on electron.

I tough about rewriting my local storage stack using indexedDB but now I'm not sure if it suffers from the same issue.

So for now I've decided to use IPC and do all local storage read/writes on the main process using node-localstorage.

@bennymeg
Copy link

LevelDB can only be accessed by by a single process at a time. So I believe the only option for now is this. Here is a simple code snippet and an article for reference that together will result in the requested behavior.

@snaildos
Copy link

Alright. Would it be possible to convert localstorage into fs ?

@joaodforce
Copy link

Alright. Would it be possible to convert localstorage into fs ?

They way I did was, was simply replacing all local storage calls with writeFileSync and readFileSync, I made the name of the key the name of the file, and the contents the body of the file.

I also made a migration script o my main process to migrate existing local storage data to FS, by iterating over the existing LocalstorageKeys.

This solution i not perfect, because it doesn't account for file locking, but my particular use case doesn't have issues with that.

@sunjinbo321
Copy link

I also encountered this problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants