mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
add a limit to the number of sessions backed up
This commit is contained in:
@@ -176,4 +176,80 @@
|
|||||||
|
|
||||||
return deferred.promise;
|
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;
|
var SNAPSHOT_INTERVAL = ONE_MINUTE * 5;
|
||||||
// Store up to 12 snapshots for a piskel session, min. 1 hour of work
|
// Store up to 12 snapshots for a piskel session, min. 1 hour of work
|
||||||
var MAX_SNAPSHOTS_PER_SESSION = 12;
|
var MAX_SNAPSHOTS_PER_SESSION = 12;
|
||||||
|
var MAX_SESSIONS = 10;
|
||||||
|
|
||||||
ns.BackupService = function (piskelController) {
|
ns.BackupService = function (piskelController, backupDatabase) {
|
||||||
this.piskelController = piskelController;
|
this.piskelController = piskelController;
|
||||||
this.lastHash = null;
|
this.lastHash = null;
|
||||||
this.nextSnapshotDate = -1;
|
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 () {
|
ns.BackupService.prototype.init = function () {
|
||||||
@@ -25,13 +27,18 @@
|
|||||||
}.bind(this));
|
}.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 () {
|
ns.BackupService.prototype.backup = function () {
|
||||||
var piskel = this.piskelController.getPiskel();
|
var piskel = this.piskelController.getPiskel();
|
||||||
var hash = piskel.getHash();
|
var hash = piskel.getHash();
|
||||||
|
|
||||||
// Do not save an unchanged piskel
|
// Do not save an unchanged piskel
|
||||||
if (hash === this.lastHash) {
|
if (hash === this.lastHash) {
|
||||||
return;
|
return Q.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the hash
|
// Update the hash
|
||||||
@@ -40,7 +47,7 @@
|
|||||||
|
|
||||||
// Prepare the backup snapshot.
|
// Prepare the backup snapshot.
|
||||||
var descriptor = piskel.getDescriptor();
|
var descriptor = piskel.getDescriptor();
|
||||||
var date = Date.now();
|
var date = this.currentDate_();
|
||||||
var snapshot = {
|
var snapshot = {
|
||||||
session_id: piskel.sessionId,
|
session_id: piskel.sessionId,
|
||||||
date: date,
|
date: date,
|
||||||
@@ -49,7 +56,7 @@
|
|||||||
serialized: pskl.utils.serialization.Serializer.serialize(piskel)
|
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];
|
var latest = snapshots[0];
|
||||||
|
|
||||||
if (latest && date < this.nextSnapshotDate) {
|
if (latest && date < this.nextSnapshotDate) {
|
||||||
@@ -64,10 +71,27 @@
|
|||||||
// remove oldest snapshot
|
// remove oldest snapshot
|
||||||
return this.backupDatabase.deleteSnapshot(snapshots[snapshots.length - 1]);
|
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));
|
||||||
}
|
}
|
||||||
}.bind(this)).catch(function (e) {
|
}.bind(this)).catch(function (e) {
|
||||||
console.log('Backup failed');
|
|
||||||
console.error(e);
|
console.error(e);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user