[Persistence] Refactor out transaction management

This commit is contained in:
Victor Woeltjen 2016-07-14 13:43:55 -07:00
parent c7529dd56b
commit a731c35ad6
3 changed files with 97 additions and 47 deletions

View File

@ -42,6 +42,7 @@ define([
"./src/representers/EditToolbarRepresenter",
"./src/capabilities/EditorCapability",
"./src/capabilities/TransactionCapabilityDecorator",
"./src/services/TransactionManager",
"./src/services/TransactionService",
"./src/creation/CreateMenuController",
"./src/creation/LocatorController",
@ -80,6 +81,7 @@ define([
EditToolbarRepresenter,
EditorCapability,
TransactionCapabilityDecorator,
TransactionManager,
TransactionService,
CreateMenuController,
LocatorController,
@ -320,7 +322,7 @@ define([
"implementation": TransactionCapabilityDecorator,
"depends": [
"$q",
"transactionService"
"transactionManager"
],
"priority": "fallback"
},
@ -405,6 +407,15 @@ define([
"key": "locator",
"template": locatorTemplate
}
],
"services": [
{
"key": "transactionManager",
"implementation": TransactionManager,
"depends": [
"transactionService"
]
}
]
}
});

View File

@ -34,69 +34,37 @@ define(
* called.
* @memberof platform/commonUI/edit/capabilities
* @param $q
* @param transactionService
* @param transactionManager
* @param persistenceCapability
* @param domainObject
* @constructor
*/
function TransactionalPersistenceCapability(
$q,
transactionService,
transactionManager,
persistenceCapability,
domainObject
) {
this.transactionService = transactionService;
this.transactionManager = transactionManager;
this.persistenceCapability = persistenceCapability;
this.domainObject = domainObject;
this.$q = $q;
}
TransactionalPersistenceCapability.prototype.transactionClearer = function (state) {
var id = this.domainObject.getId();
if (arguments.length > 0) {
TRANSACTION_SET[id] = state;
}
return TRANSACTION_SET[id];
};
/**
* The wrapped persist function. If a transaction is active, persist
* will be queued until the transaction is committed or cancelled.
* @returns {*}
*/
TransactionalPersistenceCapability.prototype.persist = function () {
var self = this;
var wrappedPersistence = this.persistenceCapability;
function onCommit() {
if (!self.transactionClearer()) {
return Promise.resolve(true);
}
return self.persistenceCapability.persist().then(function (result) {
self.transactionClearer(undefined);
return result;
});
}
function onCancel() {
if (self.domainObject.getModel().persisted !== undefined) {
//Fetch clean model from persistence
return self.persistenceCapability.refresh().then(function (result) {
self.transactionClearer(undefined);
return result;
});
} else {
self.transactionClearer(undefined);
self.removeFromTransaction = undefined;
//Model is undefined in persistence, so return undefined.
return self.$q.when(undefined);
}
}
if (this.transactionService.isActive()) {
if (!self.transactionClearer()) {
this.transactionClearer(this.transactionService
.addToTransaction(onCommit, onCancel));
}
if (this.transactionManager.isActive()) {
this.transactionManager.addToTransaction(
this.domainObject,
wrappedPersistence.persist.bind(wrappedPersistence),
wrappedPersistence.refresh.bind(wrappedPersistence)
);
//Need to return a promise from this function
return this.$q.when(true);
} else {
@ -105,10 +73,7 @@ define(
};
TransactionalPersistenceCapability.prototype.refresh = function () {
if (this.transactionClearer()) {
this.transactionClearer()();
this.transactionClearer(undefined);
}
this.transactionManager.clearTransactionsFor(this.domainObject);
return this.persistenceCapability.refresh();
};

View File

@ -0,0 +1,74 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2016, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT 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 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.
*****************************************************************************/
define([], function () {
/**
* Manages transactions to support the TransactionalPersistenceCapability.
*/
function TransactionManager(transactionService) {
this.transactionService = transactionService;
this.clearTransactionFns = {};
}
TransactionManager.prototype.isActive = function () {
return this.transactionService.isActive();
};
TransactionManager.prototype.isScheduled = function (domainObject) {
return !!this.clearTransactionFns[domainObject.getId()];
};
TransactionManager.prototype.addToTransaction = function (
domainObject,
onCommit,
onCancel
) {
var release = this.releaseClearFn.bind(this, domainObject);
function chain(promiseFn, nextFn) {
return function () {
return promiseFn().then(nextFn);
};
}
if (!this.isScheduled(domainObject)) {
this.clearTransactionFns[domainObject.getId()] =
this.transactionService.addToTransaction(
chain(onCommit, release),
chain(onCancel, release)
);
}
};
TransactionManager.prototype.clearTransactionsFor = function (domainObject) {
if (this.isScheduled(domainObject)) {
this.clearTransactionFns[domainObject.getId()]();
this.releaseClearFn(domainObject);
}
};
TransactionManager.prototype.releaseClearFn = function (domainObject) {
delete this.clearTransactionFns[domainObject.getId()];
};
return TransactionManager;
});