Open
Bug 886447
Opened 11 years ago
Updated 2 years ago
[Session Restore] Optimize communications [meta]
Categories
(Firefox :: Session Restore, task)
Firefox
Session Restore
Tracking
()
NEW
People
(Reporter: Yoric, Unassigned)
References
Details
(Keywords: main-thread-io, meta, perf, Whiteboard: [Async:team][fxperf:meta])
Attachments
(2 files, 1 obsolete file)
(deleted),
patch
|
Details | Diff | Splinter Review | |
(deleted),
image/png
|
Details |
One of the main costs of session restore is serializing + sending data across threads.
Bug 838577 and bug 867143 introduce a mechanism that lest us determine which parts of the session state has been modified since the last data collection. We can use this to only send the changed data to the I/O thread. This might complicate the code base but this has the potential to improve considerably the speed.
Reporter | ||
Updated•11 years ago
|
Assignee: nobody → dteller
Reporter | ||
Comment 1•11 years ago
|
||
Looks like if we do this, we are going to destroy one add-on:
https://addons.mozilla.org/en-US/firefox/addon/private-tab
(see https://mxr.mozilla.org/addons/source/422756/bootstrap.js#932 )
Reporter | ||
Comment 2•11 years ago
|
||
Comment 3•11 years ago
|
||
> Filed as https://github.com/Infocatcher/Private_Tab/issues/82
As I already replied on GitHub, I use "sessionstore-state-write" only to remove private tabs from session data (that tabs have associated nsILoadContext with usePrivateBrowsing == true).
So, you can filter such tabs yourself or introduce some alternative API to modify session data without unwanted deserialization/serialization calls.
Also about API. I see special handling for Scratchpad's windows, but don't see any similar API for extensions.
In other words, we currently can save some tab- and browser window-related data, but what about some "global" data?
Comment 4•11 years ago
|
||
(In reply to Infocatcher from comment #3)
> Also about API. I see special handling for Scratchpad's windows, but don't
> see any similar API for extensions.
> In other words, we currently can save some tab- and browser window-related
> data, but what about some "global" data?
You're right that this should be refactored and offered as an official API. Can you please file a separate bug for this?
Comment 5•11 years ago
|
||
(In reply to Tim Taubert [:ttaubert] from comment #4)
> You're right that this should be refactored and offered as an official API.
> Can you please file a separate bug for this?
Done: https://bugzilla.mozilla.org/show_bug.cgi?id=899213
(My English isn't so good, sorry.)
Reporter | ||
Comment 6•11 years ago
|
||
Here's a first prototype.
In the test case, this divides the size of message by ~10 after the first save.
Attachment #785899 -
Flags: feedback?(ttaubert)
Reporter | ||
Comment 7•11 years ago
|
||
Same one, but with a more meaningful test.
Attachment #785899 -
Attachment is obsolete: true
Attachment #785899 -
Flags: feedback?(ttaubert)
Attachment #785926 -
Flags: feedback?(ttaubert)
Comment 8•11 years ago
|
||
Why don't you add the new code to compress communications to _saveStateObject using stateString returned by observer?
Reporter | ||
Comment 9•11 years ago
|
||
(In reply to onemen.one from comment #8)
> Why don't you add the new code to compress communications to
> _saveStateObject using stateString returned by observer?
Because doing this would require:
1. collect state;
2. stringify full state;
3. notify observers;
4. parse modified full state;
5. compress modified full state;
6. serialize/send compressed modified full state to worker.
We have approximate benchmarks for operation 2. For ~4.5% of users (~22 million users), just this operation lasts at least 29 milliseconds on the main thread, so causes 2 frames to be skipped. Skipping 2., 3., 4. is much faster.
Comment 10•11 years ago
|
||
you are doing 1,5 and 6 anyhow.
what about this:
1. collect state;
2. give temporary public access to the value of aStateObj;
3. notify observer with an option to cancel the save;
4. check if observer did not cancel the save;
5. compress modified (or not) full state;
6. serialize/send compressed modified full state to worker.
Reporter | ||
Comment 11•11 years ago
|
||
Your idea makes sense.
However, to do it cleanly, we would need to do this with an event listener-style mechanism, rather than with an observer notification. I'd rather do that, if necessary, in a followup bug.
Comment 12•11 years ago
|
||
I'd rather evaluate if keeping the observer notification is necessary at all. So far we only have one add-on that does something we should actually do, remove private tabs. I'm very much in favor of throwing away old APIs and *maybe* replacing them by new, specialized ones.
Comment 13•11 years ago
|
||
I'm trying to improve Tabmix Session Manager and use SessionStore as much as i can.
If stringify/parse have bad impact why don't let getBrowserState/getWindowState etc.. return object instead of string
most of the time the caller have to parse the returned value any how.
Reporter | ||
Comment 14•11 years ago
|
||
(In reply to onemen.one from comment #13)
> I'm trying to improve Tabmix Session Manager and use SessionStore as much as
> i can.
>
> If stringify/parse have bad impact why don't let
> getBrowserState/getWindowState etc.. return object instead of string
>
> most of the time the caller have to parse the returned value any how.
Well, they don't do this for historical reasons. We are planning to provide better alternatives for getBrowserState, getWindowState, etc. that don't block the main thread (so, no JSON stringify/parse if possible, but also async implementation). We just haven't designed them yet.
Comment 15•11 years ago
|
||
(In reply to onemen.one from comment #13)
> I'm trying to improve Tabmix Session Manager and use SessionStore as much as
> i can.
If you have any special API requirements, please file bugs. I'd still be in favor of removing the state-write notification.
> If stringify/parse have bad impact why don't let
> getBrowserState/getWindowState etc.. return object instead of string
> most of the time the caller have to parse the returned value any how.
Yes, I totally agree. Back when SessionStore was started we didn't have the possibility to return jsvals from IDL interfaces, strings were the only method to do that. Nowadays we indeed *can* return objects but we can't easily switch to it because we'd break lots of API users.
Comment 16•11 years ago
|
||
(In reply to Tim Taubert [:ttaubert] from comment #15)
> (In reply to onemen.one from comment #13)
>
> > If stringify/parse have bad impact why don't let
> > getBrowserState/getWindowState etc.. return object instead of string
> > most of the time the caller have to parse the returned value any how.
>
> Yes, I totally agree. Back when SessionStore was started we didn't have the
> possibility to return jsvals from IDL interfaces, strings were the only
> method to do that. Nowadays we indeed *can* return objects but we can't
> easily switch to it because we'd break lots of API users.
maybe first step is to add getBrowserStateObj , getWindowStateObj without removing the current function
also need to make sure that all the get___State will have an option to get an object
Comment 17•11 years ago
|
||
(In reply to onemen.one from comment #16)
> maybe first step is to add getBrowserStateObj , getWindowStateObj without
> removing the current function
> also need to make sure that all the get___State will have an option to get
> an object
Can you give us a use case? Can you point us to an add-on that requires that functionality? I still haven't seen a valid point that convinces me we shouldn't remove the write-state notification.
To be clear, even if we would implement getBrowserStateObj etc. we would definitely not return a shared object reference. That just opens a can of worms and is really really bad API design.
Comment 18•11 years ago
|
||
(In reply to Tim Taubert [:ttaubert] from comment #17)
> Can you give us a use case? Can you point us to an add-on that requires that
> functionality? I still haven't seen a valid point that convinces me we
> shouldn't remove the write-state notification.
It would be easier if the API have function to add extra data in the session level
something like getSessionValue, setSessionValue, deleteSessionValue
> To be clear, even if we would implement getBrowserStateObj etc. we would
> definitely not return a shared object reference. That just opens a can of
> worms and is really really bad API design.
That's Ok
Regarding this bug, why you only compress tabs data, what about _closedTabs and _closedWindows both this object most of the time don't change much between each save.
one of the common action is closing tab(s), if you can some how use TabStateCache /tabInfos and pass the info to something like closedTabsCache
Comment 19•11 years ago
|
||
(In reply to onemen.one from comment #18)
> It would be easier if the API have function to add extra data in the session
> level
> something like getSessionValue, setSessionValue, deleteSessionValue
So you're saying that bug 899213 is what you want and we can get rid of the notification, right?
Depends on: 899213
Comment 20•11 years ago
|
||
(In reply to Tim Taubert [:ttaubert] from comment #19)
> (In reply to onemen.one from comment #18)
> > It would be easier if the API have function to add extra data in the session
> > level
> > something like getSessionValue, setSessionValue, deleteSessionValue
>
> So you're saying that bug 899213 is what you want and we can get rid of the
> notification, right?
Yes, as long as this bug and bug 899213 will be implement in the same Firefox version.
Comment 21•11 years ago
|
||
Sure, that's the requirement. Basically we'll make sure the SessionValue (or whatever we'll call it) API will land first. Great.
Reporter | ||
Comment 22•11 years ago
|
||
(In reply to onemen.one from comment #18)
> Regarding this bug, why you only compress tabs data, what about _closedTabs
> and _closedWindows both this object most of the time don't change much
> between each save.
> one of the common action is closing tab(s), if you can some how use
> TabStateCache /tabInfos and pass the info to something like closedTabsCache
I don't remember that we save _closedTabs and _closedWindows in sessionstore.js, do we?
Comment 23•11 years ago
|
||
Yes, we do.
Reporter | ||
Comment 24•11 years ago
|
||
In that case, this sounds like a good idea. I will investigate it.
Comment 25•11 years ago
|
||
Do you think it is possible to split sessionstore.js into 2-3 files
generalSessionData.js
openedWindows.js
closedWindows.js
you only have to write data to the file that changed
on startup you don't need to read all the closedWindows.js file at all
Reporter | ||
Comment 26•11 years ago
|
||
(In reply to onemen.one from comment #25)
> Do you think it is possible to split sessionstore.js into 2-3 files
>
> generalSessionData.js
> openedWindows.js
> closedWindows.js
>
> you only have to write data to the file that changed
> on startup you don't need to read all the closedWindows.js file at all
That sounds quite possible, at a later stage. We have discussed a few manners of cutting the data in several files to avoid too much loading/writing, and this one is definitely a possibility.
Reporter | ||
Comment 27•11 years ago
|
||
Now that bug 930967 has landed, I will try and resume work on this bug.
It is probably possible to reuse the data broadcasted by the child processes and send it immediately to the worker thread. I will investigate it. I suspect, however, that in a first version, we should keep the strategy of the above attachment.
Any thought, smacleod, ttaubert?
Flags: needinfo?(ttaubert)
Flags: needinfo?(smacleod)
Comment 28•11 years ago
|
||
Before doing something as invasive as the patch proposed here, do we have actual numbers on how much time we spend sending data around? It would be great to know beforehand whether it pays to invest time and complicate the code more.
Flags: needinfo?(ttaubert)
Updated•11 years ago
|
Attachment #785926 -
Flags: feedback?(ttaubert)
Reporter | ||
Comment 29•11 years ago
|
||
Reporter | ||
Comment 30•11 years ago
|
||
Sorry, I meant
http://telemetry.mozilla.org/#path=nightly/28/FX_SESSION_RESTORE_WRITE_FILE_LONGEST_OP_MS
+
http://telemetry.mozilla.org/#path=nightly/28/FX_SESSION_RESTORE_SERIALIZE_DATA_MS
The latter is the annoying one.
Comment 31•11 years ago
|
||
Ok, so JSON.stringify() is an overhead, as expected. Would we gain anything by getting rid of the "sessionstore-state-write" notification (what we're planning to do anyway) and sending the object to the worker and stringifying off the main thread? How would that affect WRITE_FILE_LONGEST_OP_MS?
Reporter | ||
Comment 32•11 years ago
|
||
Well, the whole plan was the following:
1. introduce some support for private tabs;
2. get rid of the sessionstore-state-write value (requires 1.);
3. optimize communications (requires 2.);
By themselves, steps 1. and 2. will not improve performance noticeably.
Comment 33•11 years ago
|
||
(In reply to Tim Taubert [:ttaubert] from comment #31)
> Ok, so JSON.stringify() is an overhead, as expected. Would we gain anything
> by getting rid of the "sessionstore-state-write" notification (what we're
> planning to do anyway) and sending the object to the worker and stringifying
> off the main thread? How would that affect WRITE_FILE_LONGEST_OP_MS?
Yeah, from looking at the Telemetry that was linked, it really seems like the bigger win would just be serializing off the main thread. Am I missing something?
Flags: needinfo?(smacleod)
Reporter | ||
Comment 34•11 years ago
|
||
(In reply to Steven MacLeod [:smacleod] from comment #33)
> Yeah, from looking at the Telemetry that was linked, it really seems like
> the bigger win would just be serializing off the main thread. Am I missing
> something?
Well, one thing: to send the data off the main thread, we need to serialize it first on the main thread. According to my benchmarks, whether we do this with JSON.stringify + TextEncoder or with postMessage doesn't change the results noticeably.
Updated•11 years ago
|
Severity: normal → major
Whiteboard: [Async:P2] → [Async:team]
Updated•11 years ago
|
Flags: firefox-backlog?
Comment 35•11 years ago
|
||
David, this sounds a lot like a meta bug. IIRC we require differential updates being sent to the worker in order to support a journaled storage. Should we file a new bug for that? Morph this one?
Flags: needinfo?(dteller)
Updated•11 years ago
|
Flags: firefox-backlog? → firefox-backlog-
Updated•10 years ago
|
Comment 38•9 years ago
|
||
I'm seeing ~500ms worth of worker.postMessage() in a profile here, immediately after 1000ms of sessionStore.getCurrentState().
Maybe it would make sense to to move the promise resolution to the macro event loop?
Reporter | ||
Comment 39•9 years ago
|
||
I had a patch that did that but died of lack of review. I haven't managed to find it, though.
Updated•7 years ago
|
Whiteboard: [Async:team] → [Async:team][fxperf]
Updated•5 years ago
|
Whiteboard: [Async:team][fxperf] → [Async:team][fxperf:meta]
Comment 40•2 years ago
|
||
In the process of migrating remaining bugs to the new severity system, the severity for this bug cannot be automatically determined. Please retriage this bug using the new severity system.
Severity: major → --
Updated•2 years ago
|
Type: defect → task
You need to log in
before you can comment on or make changes to this bug.
Description
•