Bug 1344715 - while restoring, stop collecting sessionstore data, r?mikedeboer
Add a public getter `busy` to SessionStore which returns true if restoring
Add a member `_writingStatePromise` to `SessionSaverInternal` which is null if we
are not writing state and equal to the _writeState promise otherwise.
Check `busy` in `SessionSaverInternal` `_saveState` and abort save if true.
Return a resolved promise and update time, or `_writingStatePromise` if it
is not null.
MozReview-Commit-ID: EsjkZg7yaRZ
--- a/browser/components/sessionstore/SessionSaver.jsm
+++ b/browser/components/sessionstore/SessionSaver.jsm
@@ -114,16 +114,22 @@ var SessionSaverInternal = {
/**
* A timestamp that keeps track of when we saved the session last. We will
* this to determine the correct interval between delayed saves to not deceed
* the configured session write interval.
*/
_lastSaveTime: 0,
/**
+ * A Promise that is set only when `_writeState()` is running, and `null` otherwise.
+ * It's the same promise as returned by `_writeState()`.
+ */
+ _writingStatePromise: null,
+
+ /**
* Immediately saves the current session to disk.
*/
run() {
return this._saveState(true /* force-update all windows */);
},
/**
* Saves the current session to disk delayed by a given amount of time. Should
@@ -177,16 +183,27 @@ var SessionSaverInternal = {
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
// Don't save (or even collect) anything in permanent private
// browsing mode
this.updateLastSaveTime();
return Promise.resolve();
}
+ if (SessionStore.busy) {
+ // Don't save anything if we are restoring
+ // The current time is the last save time - we are restoring
+
+ if (this._writingStatePromise) {
+ return this._writingStatePromise;
+ }
+ this.updateLastSaveTime();
+ return Promise.resolve();
+ }
+
stopWatchStart("COLLECT_DATA_MS", "COLLECT_DATA_LONGEST_OP_MS");
let state = SessionStore.getCurrentState(forceUpdateAllWindows);
PrivacyFilter.filterPrivateWindowsAndTabs(state);
// Make sure we only write worth saving tabs to disk.
SessionStore.keepOnlyWorthSavingTabs(state);
// Make sure that we keep the previous session if we started with a single
@@ -257,14 +274,19 @@ var SessionSaverInternal = {
// too soon, if saving is requested before the write completes. Without
// this update we may save repeatedly if actions cause a runDelayed
// before writing has completed. See Bug 902280
this.updateLastSaveTime();
// Write (atomically) to a session file, using a tmp file. Once the session
// file is successfully updated, save the time stamp of the last save and
// notify the observers.
- return SessionFile.write(state).then(() => {
+ this._writingStatePromise = SessionFile.write(state).then(() => {
+ this._writingStatePromise = null;
this.updateLastSaveTime();
notify(null, "sessionstore-state-write-complete");
- }, console.error);
+ }).catch(err => {
+ this._writingStatePromise = null;
+ console.error(err);
+ });
+ return this._writingStatePromise;
},
};
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -209,16 +209,27 @@ this.SessionStore = {
get canRestoreLastSession() {
return SessionStoreInternal.canRestoreLastSession;
},
set canRestoreLastSession(val) {
SessionStoreInternal.canRestoreLastSession = val;
},
+ get busy() {
+ // We need to check if we're setting the browser state
+ // (using _browserSetState) or if there exists a
+ // tab or window being restored (using _windows[id].busy)
+ // We use `sort` and `reverse` since the last window is more likely
+ // to be busy if we're restoring multiple windows
+ return SessionStoreInternal._browserSetState ||
+ Object.getOwnPropertyNames(SessionStoreInternal._windows)
+ .sort().reverse().some(id => SessionStoreInternal._windows[id].busy);
+ },
+
get lastClosedObjectType() {
return SessionStoreInternal.lastClosedObjectType;
},
init: function ss_init() {
SessionStoreInternal.init();
},