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

View File

@ -34,69 +34,37 @@ define(
* called. * called.
* @memberof platform/commonUI/edit/capabilities * @memberof platform/commonUI/edit/capabilities
* @param $q * @param $q
* @param transactionService * @param transactionManager
* @param persistenceCapability * @param persistenceCapability
* @param domainObject * @param domainObject
* @constructor * @constructor
*/ */
function TransactionalPersistenceCapability( function TransactionalPersistenceCapability(
$q, $q,
transactionService, transactionManager,
persistenceCapability, persistenceCapability,
domainObject domainObject
) { ) {
this.transactionService = transactionService; this.transactionManager = transactionManager;
this.persistenceCapability = persistenceCapability; this.persistenceCapability = persistenceCapability;
this.domainObject = domainObject; this.domainObject = domainObject;
this.$q = $q; 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 * The wrapped persist function. If a transaction is active, persist
* will be queued until the transaction is committed or cancelled. * will be queued until the transaction is committed or cancelled.
* @returns {*} * @returns {*}
*/ */
TransactionalPersistenceCapability.prototype.persist = function () { TransactionalPersistenceCapability.prototype.persist = function () {
var self = this; var wrappedPersistence = this.persistenceCapability;
function onCommit() { if (this.transactionManager.isActive()) {
if (!self.transactionClearer()) { this.transactionManager.addToTransaction(
return Promise.resolve(true); this.domainObject,
} wrappedPersistence.persist.bind(wrappedPersistence),
return self.persistenceCapability.persist().then(function (result) { wrappedPersistence.refresh.bind(wrappedPersistence)
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));
}
//Need to return a promise from this function //Need to return a promise from this function
return this.$q.when(true); return this.$q.when(true);
} else { } else {
@ -105,10 +73,7 @@ define(
}; };
TransactionalPersistenceCapability.prototype.refresh = function () { TransactionalPersistenceCapability.prototype.refresh = function () {
if (this.transactionClearer()) { this.transactionManager.clearTransactionsFor(this.domainObject);
this.transactionClearer()();
this.transactionClearer(undefined);
}
return this.persistenceCapability.refresh(); 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;
});