[Persistence] Remove obsolete caching decorator

#831
This commit is contained in:
Victor Woeltjen 2016-04-14 10:15:40 -07:00
parent 00bf05c929
commit ffd5faf9a2
4 changed files with 0 additions and 358 deletions

View File

@ -1,2 +0,0 @@
This bundle introduces a persistence cache to Open MCT Web to
limit the number of persistence requests issued by the platform.

View File

@ -1,49 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/CachingPersistenceDecorator",
'legacyRegistry'
], function (
CachingPersistenceDecorator,
legacyRegistry
) {
"use strict";
legacyRegistry.register("platform/persistence/cache", {
"name": "Persistence cache",
"description": "Cache to improve availability of persisted objects.",
"extensions": {
"components": [
{
"provides": "persistenceService",
"type": "decorator",
"implementation": CachingPersistenceDecorator,
"depends": [
"PERSISTENCE_SPACE"
]
}
]
}
});
});

View File

@ -1,163 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
/**
* This bundle decorates the persistence service to maintain a local cache
* of persisted documents.
* @namespace platform/persistence/cache
*/
define(
[],
function () {
'use strict';
/**
* A caching persistence decorator maintains local copies of persistent objects
* that have been loaded, and keeps them in sync after writes. This allows
* retrievals to occur more quickly after the first load.
*
* @memberof platform/persistence/cache
* @constructor
* @param {string[]} cacheSpaces persistence space names which
* should be cached
* @param {PersistenceService} persistenceService the service which
* implements object persistence, whose inputs/outputs
* should be cached.
* @implements {PersistenceService}
*/
function CachingPersistenceDecorator(cacheSpaces, persistenceService) {
var spaces = cacheSpaces || [], // List of spaces to cache
cache = {}; // Where objects will be stored
// Arrayify list of spaces to cache, if necessary.
spaces = Array.isArray(spaces) ? spaces : [ spaces ];
// Initialize caches
spaces.forEach(function (space) {
cache[space] = {};
});
this.spaces = spaces;
this.cache = cache;
this.persistenceService = persistenceService;
}
// Wrap as a thenable; used instead of $q.when because that
// will resolve on a future tick, which can cause latency
// issues (which this decorator is intended to address.)
function fastPromise(value) {
return {
then: function (callback) {
return fastPromise(callback(value));
}
};
}
// Update the cached instance of an object to a new value
function replaceValue(valueHolder, newValue) {
var v = valueHolder.value;
// If it's a JS object, we want to replace contents, so that
// everybody gets the same instance.
if (typeof v === 'object' && v !== null) {
// Only update contents if these are different instances
if (v !== newValue) {
// Clear prior contents
Object.keys(v).forEach(function (k) {
delete v[k];
});
// Shallow-copy contents
Object.keys(newValue).forEach(function (k) {
v[k] = newValue[k];
});
}
} else {
// Otherwise, just store the new value
valueHolder.value = newValue;
}
}
// Place value in the cache for space, if there is one.
CachingPersistenceDecorator.prototype.addToCache = function (space, key, value) {
var cache = this.cache;
if (cache[space]) {
if (cache[space][key]) {
replaceValue(cache[space][key], value);
} else {
cache[space][key] = { value: value };
}
}
};
// Create a function for putting value into a cache;
// useful for then-chaining.
CachingPersistenceDecorator.prototype.putCache = function (space, key) {
var self = this;
return function (value) {
self.addToCache(space, key, value);
return value;
};
};
CachingPersistenceDecorator.prototype.listSpaces = function () {
return this.persistenceService.listSpaces();
};
CachingPersistenceDecorator.prototype.listObjects = function (space) {
return this.persistenceService.listObjects(space);
};
CachingPersistenceDecorator.prototype.createObject = function (space, key, value) {
this.addToCache(space, key, value);
return this.persistenceService.createObject(space, key, value);
};
CachingPersistenceDecorator.prototype.readObject = function (space, key) {
var cache = this.cache;
return (cache[space] && cache[space][key]) ?
fastPromise(cache[space][key].value) :
this.persistenceService.readObject(space, key)
.then(this.putCache(space, key));
};
CachingPersistenceDecorator.prototype.updateObject = function (space, key, value) {
var self = this;
return this.persistenceService.updateObject(space, key, value)
.then(function (result) {
self.addToCache(space, key, value);
return result;
});
};
CachingPersistenceDecorator.prototype.deleteObject = function (space, key, value) {
if (this.cache[space]) {
delete this.cache[space][key];
}
return this.persistenceService.deleteObject(space, key, value);
};
return CachingPersistenceDecorator;
}
);

View File

@ -1,144 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
define(
["../src/CachingPersistenceDecorator"],
function (CachingPersistenceDecorator) {
"use strict";
var PERSISTENCE_METHODS = [
"listSpaces",
"listObjects",
"createObject",
"readObject",
"updateObject",
"deleteObject"
];
describe("The caching persistence decorator", function () {
var testSpace,
mockPersistence,
mockCallback,
decorator;
function mockPromise(value) {
return {
then: function (callback) {
return mockPromise(callback(value));
}
};
}
beforeEach(function () {
testSpace = "TEST";
mockPersistence = jasmine.createSpyObj(
"persistenceService",
PERSISTENCE_METHODS
);
mockCallback = jasmine.createSpy("callback");
PERSISTENCE_METHODS.forEach(function (m) {
mockPersistence[m].andReturn(mockPromise({
method: m
}));
});
decorator = new CachingPersistenceDecorator(
testSpace,
mockPersistence
);
});
it("delegates all methods", function () {
PERSISTENCE_METHODS.forEach(function (m) {
// Reset the callback
mockCallback = jasmine.createSpy("callback");
// Invoke the method; avoid using a key that will be cached
decorator[m](testSpace, "testKey" + m, "testValue")
.then(mockCallback);
// Should have gotten that method's plain response
expect(mockCallback).toHaveBeenCalledWith({ method: m });
});
});
it("does not repeat reads of cached objects", function () {
// Perform two reads
decorator.readObject(testSpace, "someKey", "someValue")
.then(mockCallback);
decorator.readObject(testSpace, "someKey", "someValue")
.then(mockCallback);
// Should have only delegated once
expect(mockPersistence.readObject.calls.length).toEqual(1);
// But both promises should have resolved
expect(mockCallback.calls.length).toEqual(2);
});
it("gives a single instance of cached objects", function () {
// Perform two reads
decorator.readObject(testSpace, "someKey", "someValue")
.then(mockCallback);
decorator.readObject(testSpace, "someKey", "someValue")
.then(mockCallback);
// Results should have been pointer-identical
expect(mockCallback.calls[0].args[0])
.toBe(mockCallback.calls[1].args[0]);
});
it("maintains the same cached instance between reads/writes", function () {
var testObject = { abc: "XYZ!" };
// Perform two reads with a write in between
decorator.readObject(testSpace, "someKey", "someValue")
.then(mockCallback);
decorator.updateObject(testSpace, "someKey", testObject);
decorator.readObject(testSpace, "someKey", "someValue")
.then(mockCallback);
// Results should have been pointer-identical
expect(mockCallback.calls[0].args[0])
.toBe(mockCallback.calls[1].args[0]);
// But contents should have been equal to the written object
expect(mockCallback).toHaveBeenCalledWith(testObject);
});
it("is capable of reading/writing strings", function () {
// Efforts made to keep cached objects pointer-identical
// would break on strings - so make sure cache isn't
// breaking when we read/write strings.
decorator.createObject(testSpace, "someKey", "someValue");
decorator.updateObject(testSpace, "someKey", "someOtherValue");
decorator.readObject(testSpace, "someKey").then(mockCallback);
expect(mockCallback).toHaveBeenCalledWith("someOtherValue");
});
});
}
);