add a limit to the number of sessions backed up
This commit is contained in:
parent
f9570ea3c5
commit
c6e106fe2d
2 changed files with 106 additions and 6 deletions
|
@ -176,4 +176,80 @@
|
|||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ns.BackupDatabase.prototype.getSessions = function () {
|
||||
// Create the backup promise.
|
||||
var deferred = Q.defer();
|
||||
|
||||
// Open a transaction to the snapshots object store.
|
||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
||||
|
||||
var sessions = {};
|
||||
|
||||
var _createSession = function (snapshot) {
|
||||
sessions[snapshot.sessionId] = {
|
||||
startDate: snapshot.date,
|
||||
endDate: snapshot.date,
|
||||
name: snapshot.name,
|
||||
id: snapshot.sessionId
|
||||
};
|
||||
};
|
||||
|
||||
var _updateSessions = function (snapshot) {
|
||||
var s = sessions[snapshot.sessionId];
|
||||
s.startDate = Math.min(s.startDate, snapshot.startDate);
|
||||
s.endDate = Math.max(s.endDate, snapshot.endDate);
|
||||
if (s.endDate === snapshot.endDate) {
|
||||
s.name = snapshot.name;
|
||||
}
|
||||
};
|
||||
|
||||
var index = objectStore.index('date');
|
||||
var range = IDBKeyRange.upperBound(Infinity);
|
||||
index.openCursor(range, 'prev').onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
var snapshot = cursor && cursor.value;
|
||||
if (!snapshot) {
|
||||
deferred.resolve(sessions);
|
||||
} else {
|
||||
if (sessions[snapshot.sessionId]) {
|
||||
_createSession(snapshot);
|
||||
} else {
|
||||
_updateSessions(snapshot);
|
||||
}
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
|
||||
return deferred.promise.then(function (sessions) {
|
||||
// Convert the sessions map to an array.
|
||||
return Object.keys(sessions).map(function (key) {
|
||||
return sessions[key];
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
ns.BackupDatabase.prototype.deleteSnapshotsForSession = function (sessionId) {
|
||||
// Create the backup promise.
|
||||
var deferred = Q.defer();
|
||||
|
||||
// Open a transaction to the snapshots object store.
|
||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
||||
|
||||
// Loop on all the saved snapshots for the provided piskel id
|
||||
var index = objectStore.index('session_id');
|
||||
var keyRange = IDBKeyRange.only(sessionId);
|
||||
|
||||
index.openCursor(keyRange).onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
cursor.delete();
|
||||
cursor.continue();
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -10,13 +10,15 @@
|
|||
var SNAPSHOT_INTERVAL = ONE_MINUTE * 5;
|
||||
// Store up to 12 snapshots for a piskel session, min. 1 hour of work
|
||||
var MAX_SNAPSHOTS_PER_SESSION = 12;
|
||||
var MAX_SESSIONS = 10;
|
||||
|
||||
ns.BackupService = function (piskelController) {
|
||||
ns.BackupService = function (piskelController, backupDatabase) {
|
||||
this.piskelController = piskelController;
|
||||
this.lastHash = null;
|
||||
this.nextSnapshotDate = -1;
|
||||
|
||||
this.backupDatabase = new pskl.database.BackupDatabase();
|
||||
// backupDatabase can be provided for testing purposes.
|
||||
this.backupDatabase = backupDatabase || new pskl.database.BackupDatabase();
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.init = function () {
|
||||
|
@ -25,13 +27,18 @@
|
|||
}.bind(this));
|
||||
};
|
||||
|
||||
// This is purely exposed for testing, so that backup dates can be set programmatically.
|
||||
ns.BackupService.prototype.currentDate_ = function () {
|
||||
return Date.now();
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.backup = function () {
|
||||
var piskel = this.piskelController.getPiskel();
|
||||
var hash = piskel.getHash();
|
||||
|
||||
// Do not save an unchanged piskel
|
||||
if (hash === this.lastHash) {
|
||||
return;
|
||||
return Q.resolve();
|
||||
}
|
||||
|
||||
// Update the hash
|
||||
|
@ -40,7 +47,7 @@
|
|||
|
||||
// Prepare the backup snapshot.
|
||||
var descriptor = piskel.getDescriptor();
|
||||
var date = Date.now();
|
||||
var date = this.currentDate_();
|
||||
var snapshot = {
|
||||
session_id: piskel.sessionId,
|
||||
date: date,
|
||||
|
@ -49,7 +56,7 @@
|
|||
serialized: pskl.utils.serialization.Serializer.serialize(piskel)
|
||||
};
|
||||
|
||||
this.backupDatabase.getSnapshotsBySessionId(piskel.sessionId).then(function (snapshots) {
|
||||
return this.backupDatabase.getSnapshotsBySessionId(piskel.sessionId).then(function (snapshots) {
|
||||
var latest = snapshots[0];
|
||||
|
||||
if (latest && date < this.nextSnapshotDate) {
|
||||
|
@ -64,10 +71,27 @@
|
|||
// remove oldest snapshot
|
||||
return this.backupDatabase.deleteSnapshot(snapshots[snapshots.length - 1]);
|
||||
}
|
||||
}.bind(this)).then(function () {
|
||||
var isNewSession = !latest;
|
||||
if (!isNewSession) {
|
||||
return;
|
||||
}
|
||||
return this.backupDatabase.getSessions().then(function (sessions) {
|
||||
if (sessions.length <= MAX_SESSIONS) {
|
||||
// If MAX_SESSIONS has not been reached, no need to delete
|
||||
// previous sessions.
|
||||
return;
|
||||
}
|
||||
|
||||
var oldestSession = sessions.sort(function (s1, s2) {
|
||||
return s1.startDate - s2.startDate;
|
||||
})[0].id;
|
||||
|
||||
return this.backupDatabase.deleteSnapshotsForSession(oldestSession);
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}
|
||||
}.bind(this)).catch(function (e) {
|
||||
console.log('Backup failed');
|
||||
console.error(e);
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue