-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Enable active client manager, multiple tabs, and previous PR cleanup #469
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
Changes from 20 commits
3d6b637
8814c20
fa99401
0da38df
61aaa85
1720bad
1fa3262
21ce6dc
aa4811f
fe8fc83
47d0ca1
cb67d7e
abc9cb0
457f1bb
2992aa0
228bc2d
232192d
20b9be5
a418d90
38c19e1
3166611
90ea5a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import _ from 'underscore'; | ||
| import Guid from '../Guid'; | ||
| import Ion from '../Ion'; | ||
| import IONKEYS from '../../IONKEYS'; | ||
|
|
||
| const clientID = Guid(); | ||
| const maxClients = 20; | ||
|
|
||
| let activeClients; | ||
| Ion.connect({ | ||
| key: IONKEYS.ACTIVE_CLIENTS, | ||
|
|
||
| callback: (val) => { | ||
| activeClients = val; | ||
| if (activeClients.length >= maxClients) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we need to update active clients in Ion in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see why we would, no. Can you explain why you're thinking it would be necessary? If you added a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think I fully understood how this works yesterday, but I think I get it now. When
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep! Exactly. |
||
| activeClients.shift(); | ||
| Ion.set(IONKEYS.ACTIVE_CLIENTS, activeClients); | ||
| } | ||
| }, | ||
| }); | ||
|
|
||
| /** | ||
| * Add our client ID to the list of active IDs | ||
| */ | ||
| function init() { | ||
| Ion.merge(IONKEYS.ACTIVE_CLIENTS, [clientID]); | ||
| } | ||
|
|
||
| /** | ||
| * The last GUID is the most recent GUID, so that should be the leader | ||
| * | ||
| * @returns {boolean} | ||
| */ | ||
| function isClientTheLeader() { | ||
| return _.last(activeClients) === clientID; | ||
| } | ||
|
|
||
| export { | ||
| init, | ||
| isClientTheLeader | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /** | ||
| * For native devices, there will never be more than one | ||
| * client running at a time, so this lib is a big no-op | ||
| */ | ||
|
|
||
| function init() {} | ||
| function isClientTheLeader() { | ||
| return true; | ||
| } | ||
|
|
||
| export { | ||
| init, | ||
| isClientTheLeader | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| /** | ||
| * Listens for storage events so that multiple tabs can keep track of what | ||
| * other tabs are doing | ||
| * | ||
| * @param {function} callback | ||
| */ | ||
| function addStorageEventHandler(callback) { | ||
| window.addEventListener('storage', (e) => { | ||
| let newValue; | ||
| try { | ||
| newValue = JSON.parse(e.newValue); | ||
| } catch (err) { | ||
| console.error('Could not parse the newValue of the storage event', err, e); | ||
| } | ||
| callback(e.key, JSON.parse(newValue)); | ||
|
||
| }); | ||
| } | ||
|
|
||
| export default addStorageEventHandler; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| /** | ||
| * Native clients don't have storage events and that's OK because | ||
| * you can't have multiple native clients open at the same time on the same | ||
| * device | ||
| */ | ||
| function addStorageEventHandler() {} | ||
|
|
||
| export default addStorageEventHandler; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it was intentional... and I'm open to a better solution. The problem is that these were stored as an object before, and sense we are only calling
Ion.merge()for this, moving from an object to an array is not possible and will result in really bad values being stored.One possible solution is to rename it to maybe
activeClientIDs, then add some code which clears outactiveClients, and then after a week, we can go back and set it back toactiveClients. Whatever solution we think of here, we should try to find some kind of method that is fairly reproducible because I think we will need to do this occassionally.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok changing the name works for now!
I think learn term we need a way to perform
localStoragemigrations for when keys change by adding some kind of instructions before the app updates or inits. That might mean we have some migration code running that based on the version will alter thelocalStorageschema or simply blow it away and start over from scratch minus session information.Seems like a similar problem people run into when implementing a
ServiceWorkerThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this. The way I imagine this would work is something like
That should all be transparent to the user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think the catch there is that process wouldn't be exactly "transparent" to the user, particularly the "load everything from scratch" part. I'm going to spin up an issue so we can discuss this further and plan on leaving this code the way it is for now.