Updated SingletonManager
This commit is contained in:
@@ -296,7 +296,7 @@ angular.module('app.frontend')
|
|||||||
let prefsContentType = "SN|UserPreferences";
|
let prefsContentType = "SN|UserPreferences";
|
||||||
|
|
||||||
singletonManager.registerSingleton({content_type: prefsContentType}, (resolvedSingleton) => {
|
singletonManager.registerSingleton({content_type: prefsContentType}, (resolvedSingleton) => {
|
||||||
console.log("AuthManager received resolved", resolvedSingleton);
|
console.log("AuthManager received resolved UserPreferences", resolvedSingleton);
|
||||||
this.userPreferences = resolvedSingleton;
|
this.userPreferences = resolvedSingleton;
|
||||||
}, () => {
|
}, () => {
|
||||||
// Safe to create. Create and return object.
|
// Safe to create. Create and return object.
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ class ComponentManager {
|
|||||||
recursion caused by the component being modified and saved after it is updated.
|
recursion caused by the component being modified and saved after it is updated.
|
||||||
*/
|
*/
|
||||||
if(syncedComponents.length > 0 && source != ModelManager.MappingSourceRemoteSaved) {
|
if(syncedComponents.length > 0 && source != ModelManager.MappingSourceRemoteSaved) {
|
||||||
console.log("Web, Syncing Components", syncedComponents, "source", source);
|
|
||||||
// Ensure any component in our data is installed by the system
|
// Ensure any component in our data is installed by the system
|
||||||
this.desktopManager.syncComponentsInstallation(syncedComponents);
|
this.desktopManager.syncComponentsInstallation(syncedComponents);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
The SingletonManager allows controllers to register an item as a singleton, which means only one instance of that model
|
The SingletonManager allows controllers to register an item as a singleton, which means only one instance of that model
|
||||||
should exist, both on the server and on the client. When the SingletonManager detects multiple items matching the singleton predicate,
|
should exist, both on the server and on the client. When the SingletonManager detects multiple items matching the singleton predicate,
|
||||||
the oldest ones will be deleted, leaving the newest ones
|
the oldest ones will be deleted, leaving the newest ones.
|
||||||
|
|
||||||
|
We will treat the model most recently arrived from the server as the most recent one. The reason for this is, if you're offline,
|
||||||
|
a singleton can be created, as in the case of UserPreferneces. Then when you sign in, you'll retrieve your actual user preferences.
|
||||||
|
In that case, even though the offline singleton has a more recent updated_at, the server retreived value is the one we care more about.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SingletonManager {
|
class SingletonManager {
|
||||||
@@ -16,13 +20,14 @@ class SingletonManager {
|
|||||||
})
|
})
|
||||||
|
|
||||||
$rootScope.$on("sync:completed", (event, data) => {
|
$rootScope.$on("sync:completed", (event, data) => {
|
||||||
console.log("Sync completed", data);
|
|
||||||
this.resolveSingletons(data.retrievedItems || []);
|
this.resolveSingletons(data.retrievedItems || []);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Testing code to make sure only 1 exists
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
var userPrefsTotal = modelManager.itemsForContentType("SN|UserPreferences");
|
var userPrefs = modelManager.itemsForContentType("SN|UserPreferences");
|
||||||
console.log("All extant prefs", userPrefsTotal);
|
console.assert(userPrefs.length == 1);
|
||||||
|
console.log("All extant prefs", userPrefs);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,25 +49,46 @@ class SingletonManager {
|
|||||||
var predicate = singletonHandler.predicate;
|
var predicate = singletonHandler.predicate;
|
||||||
var singletonItems = this.filterItemsWithPredicate(retrievedItems, predicate);
|
var singletonItems = this.filterItemsWithPredicate(retrievedItems, predicate);
|
||||||
if(singletonItems.length > 0) {
|
if(singletonItems.length > 0) {
|
||||||
// Check local inventory and make sure only 1 similar item exists. If more than 1, delete oldest
|
/*
|
||||||
|
Check local inventory and make sure only 1 similar item exists. If more than 1, delete oldest
|
||||||
|
Note that this local inventory will also contain whatever is in retrievedItems.
|
||||||
|
However, as stated in the header comment, retrievedItems take precendence over existing items,
|
||||||
|
even if they have a lower updated_at value
|
||||||
|
*/
|
||||||
var allExtantItemsMatchingPredicate = this.filterItemsWithPredicate(this.modelManager.allItems, predicate);
|
var allExtantItemsMatchingPredicate = this.filterItemsWithPredicate(this.modelManager.allItems, predicate);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If there are more than 1 matches, delete everything not in `singletonItems`,
|
||||||
|
then delete all but the latest in `singletonItems`
|
||||||
|
*/
|
||||||
if(allExtantItemsMatchingPredicate.length >= 2) {
|
if(allExtantItemsMatchingPredicate.length >= 2) {
|
||||||
// Purge old ones
|
var toDelete = [];
|
||||||
var sorted = allExtantItemsMatchingPredicate.sort((a, b) => {
|
for(var extantItem of allExtantItemsMatchingPredicate) {
|
||||||
|
if(!singletonItems.includes(extantItem)) {
|
||||||
|
// Delete it
|
||||||
|
toDelete.push(extantItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort incoming singleton items by most recently updated first, then delete all the rest
|
||||||
|
var sorted = singletonItems.sort((a, b) => {
|
||||||
return a.updated_at < b.updated_at;
|
return a.updated_at < b.updated_at;
|
||||||
})
|
})
|
||||||
|
|
||||||
var toDelete = sorted.slice(1, sorted.length);
|
// Delete everything but the first one
|
||||||
|
toDelete = toDelete.concat(sorted.slice(1, sorted.length));
|
||||||
|
|
||||||
for(var d of toDelete) {
|
for(var d of toDelete) {
|
||||||
this.modelManager.setItemToBeDeleted(d);
|
this.modelManager.setItemToBeDeleted(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$rootScope.sync();
|
this.$rootScope.sync();
|
||||||
|
|
||||||
// Send remaining item to callback
|
// Send remaining item to callback
|
||||||
var singleton = sorted[0];
|
var singleton = sorted[0];
|
||||||
singletonHandler.singleton = singleton;
|
singletonHandler.singleton = singleton;
|
||||||
singletonHandler.resolutionCallback(singleton);
|
singletonHandler.resolutionCallback(singleton);
|
||||||
|
|
||||||
} else if(allExtantItemsMatchingPredicate.length == 1) {
|
} else if(allExtantItemsMatchingPredicate.length == 1) {
|
||||||
if(!singletonHandler.singleton) {
|
if(!singletonHandler.singleton) {
|
||||||
// Not yet notified interested parties of object
|
// Not yet notified interested parties of object
|
||||||
|
|||||||
Reference in New Issue
Block a user