mirror of
https://github.com/nasa/openmct.git
synced 2025-05-22 02:07:42 +00:00
[Persistence] Refactor out Transaction
https://github.com/nasa/openmct/pull/874#issuecomment-233068178
This commit is contained in:
parent
766e94ed62
commit
6c4419fb72
63
platform/commonUI/edit/src/services/Transaction.js
Normal file
63
platform/commonUI/edit/src/services/Transaction.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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 () {
|
||||||
|
function Transaction($log) {
|
||||||
|
this.$log = $log;
|
||||||
|
this.callbacks = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
Transaction.prototype.add = function (commit, cancel) {
|
||||||
|
var callback = { commit: commit, cancel: cancel };
|
||||||
|
this.callbacks.push(callback);
|
||||||
|
return function () {
|
||||||
|
this.callbacks = this.callbacks.filter(function (c) {
|
||||||
|
return c !== callback;
|
||||||
|
});
|
||||||
|
}.bind(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
Transaction.prototype.size = function () {
|
||||||
|
return this.callbacks.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
['commit', 'cancel'].forEach(function (method) {
|
||||||
|
Transaction.prototype[method] = function () {
|
||||||
|
var promises = [];
|
||||||
|
var callback;
|
||||||
|
|
||||||
|
while (this.callbacks.length > 0) {
|
||||||
|
callback = this.callbacks.shift();
|
||||||
|
try {
|
||||||
|
promises.push(callback[method]());
|
||||||
|
} catch (e) {
|
||||||
|
this.$log
|
||||||
|
.error("Error trying to " + method + " transaction.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return Transaction;
|
||||||
|
});
|
@ -21,8 +21,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*global define*/
|
/*global define*/
|
||||||
define(
|
define(
|
||||||
[],
|
['./Transaction'],
|
||||||
function () {
|
function (Transaction) {
|
||||||
/**
|
/**
|
||||||
* Implements an application-wide transaction state. Once a
|
* Implements an application-wide transaction state. Once a
|
||||||
* transaction is started, calls to
|
* transaction is started, calls to
|
||||||
@ -37,10 +37,7 @@ define(
|
|||||||
function TransactionService($q, $log) {
|
function TransactionService($q, $log) {
|
||||||
this.$q = $q;
|
this.$q = $q;
|
||||||
this.$log = $log;
|
this.$log = $log;
|
||||||
this.transaction = false;
|
this.transaction = undefined;
|
||||||
|
|
||||||
this.onCommits = [];
|
|
||||||
this.onCancels = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,14 +51,14 @@ define(
|
|||||||
//Log error because this is a programming error if it occurs.
|
//Log error because this is a programming error if it occurs.
|
||||||
this.$log.error("Transaction already in progress");
|
this.$log.error("Transaction already in progress");
|
||||||
}
|
}
|
||||||
this.transaction = true;
|
this.transaction = new Transaction(this.$log);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {boolean} If true, indicates that a transaction is in progress
|
* @returns {boolean} If true, indicates that a transaction is in progress
|
||||||
*/
|
*/
|
||||||
TransactionService.prototype.isActive = function () {
|
TransactionService.prototype.isActive = function () {
|
||||||
return this.transaction;
|
return !!this.transaction;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,23 +70,11 @@ define(
|
|||||||
*/
|
*/
|
||||||
TransactionService.prototype.addToTransaction = function (onCommit, onCancel) {
|
TransactionService.prototype.addToTransaction = function (onCommit, onCancel) {
|
||||||
if (this.transaction) {
|
if (this.transaction) {
|
||||||
this.onCommits.push(onCommit);
|
return this.transaction.add(onCommit, onCancel);
|
||||||
if (onCancel) {
|
|
||||||
this.onCancels.push(onCancel);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//Log error because this is a programming error if it occurs.
|
//Log error because this is a programming error if it occurs.
|
||||||
this.$log.error("No transaction in progress");
|
this.$log.error("No transaction in progress");
|
||||||
}
|
}
|
||||||
|
|
||||||
return function () {
|
|
||||||
this.onCommits = this.onCommits.filter(function (callback) {
|
|
||||||
return callback !== onCommit;
|
|
||||||
});
|
|
||||||
this.onCancels = this.onCancels.filter(function (callback) {
|
|
||||||
return callback !== onCancel;
|
|
||||||
});
|
|
||||||
}.bind(this);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,24 +85,9 @@ define(
|
|||||||
* completed. Will reject if any commit operations fail
|
* completed. Will reject if any commit operations fail
|
||||||
*/
|
*/
|
||||||
TransactionService.prototype.commit = function () {
|
TransactionService.prototype.commit = function () {
|
||||||
var self = this,
|
var transaction = this.transaction;
|
||||||
promises = [],
|
this.transaction = undefined;
|
||||||
onCommit;
|
return transaction && transaction.commit();
|
||||||
|
|
||||||
while (this.onCommits.length > 0) { // ...using a while in case some onCommit adds to transaction
|
|
||||||
onCommit = this.onCommits.pop();
|
|
||||||
try { // ...also don't want to fail mid-loop...
|
|
||||||
promises.push(onCommit());
|
|
||||||
} catch (e) {
|
|
||||||
this.$log.error("Error committing transaction.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.$q.all(promises).then(function () {
|
|
||||||
self.transaction = false;
|
|
||||||
|
|
||||||
self.onCommits = [];
|
|
||||||
self.onCancels = [];
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,28 +99,13 @@ define(
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
TransactionService.prototype.cancel = function () {
|
TransactionService.prototype.cancel = function () {
|
||||||
var self = this,
|
var transaction = this.transaction;
|
||||||
results = [],
|
this.transaction = undefined;
|
||||||
onCancel;
|
return transaction && transaction.cancel();
|
||||||
|
|
||||||
while (this.onCancels.length > 0) {
|
|
||||||
onCancel = this.onCancels.pop();
|
|
||||||
try {
|
|
||||||
results.push(onCancel());
|
|
||||||
} catch (error) {
|
|
||||||
this.$log.error("Error committing transaction.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.$q.all(results).then(function () {
|
|
||||||
self.transaction = false;
|
|
||||||
|
|
||||||
self.onCommits = [];
|
|
||||||
self.onCancels = [];
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionService.prototype.size = function () {
|
TransactionService.prototype.size = function () {
|
||||||
return this.onCommits.length;
|
return this.transaction ? this.transaction.size() : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
return TransactionService;
|
return TransactionService;
|
||||||
|
@ -57,8 +57,7 @@ define(
|
|||||||
|
|
||||||
transactionService.startTransaction();
|
transactionService.startTransaction();
|
||||||
transactionService.addToTransaction(onCommit, onCancel);
|
transactionService.addToTransaction(onCommit, onCancel);
|
||||||
expect(transactionService.onCommits.length).toBe(1);
|
expect(transactionService.size()).toBe(1);
|
||||||
expect(transactionService.onCancels.length).toBe(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("size function returns size of commit and cancel queues", function () {
|
it("size function returns size of commit and cancel queues", function () {
|
||||||
@ -85,7 +84,7 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("commit calls all queued commit functions", function () {
|
it("commit calls all queued commit functions", function () {
|
||||||
expect(transactionService.onCommits.length).toBe(3);
|
expect(transactionService.size()).toBe(3);
|
||||||
transactionService.commit();
|
transactionService.commit();
|
||||||
onCommits.forEach(function (spy) {
|
onCommits.forEach(function (spy) {
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
@ -95,8 +94,8 @@ define(
|
|||||||
it("commit resets active state and clears queues", function () {
|
it("commit resets active state and clears queues", function () {
|
||||||
transactionService.commit();
|
transactionService.commit();
|
||||||
expect(transactionService.isActive()).toBe(false);
|
expect(transactionService.isActive()).toBe(false);
|
||||||
expect(transactionService.onCommits.length).toBe(0);
|
expect(transactionService.size()).toBe(0);
|
||||||
expect(transactionService.onCancels.length).toBe(0);
|
expect(transactionService.size()).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -116,7 +115,7 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("cancel calls all queued cancel functions", function () {
|
it("cancel calls all queued cancel functions", function () {
|
||||||
expect(transactionService.onCancels.length).toBe(3);
|
expect(transactionService.size()).toBe(3);
|
||||||
transactionService.cancel();
|
transactionService.cancel();
|
||||||
onCancels.forEach(function (spy) {
|
onCancels.forEach(function (spy) {
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
@ -126,8 +125,7 @@ define(
|
|||||||
it("cancel resets active state and clears queues", function () {
|
it("cancel resets active state and clears queues", function () {
|
||||||
transactionService.cancel();
|
transactionService.cancel();
|
||||||
expect(transactionService.isActive()).toBe(false);
|
expect(transactionService.isActive()).toBe(false);
|
||||||
expect(transactionService.onCommits.length).toBe(0);
|
expect(transactionService.size()).toBe(0);
|
||||||
expect(transactionService.onCancels.length).toBe(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user