aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarkko Pöyry <jpoyry@google.com>2015-05-21 14:56:02 -0700
committerJarkko Pöyry <jpoyry@google.com>2015-07-28 20:18:13 -0700
commitf6b3b95d6fc51e6cc9daf3d51521115ebec039b8 (patch)
tree97b0428805b69661f0b63cdd2f0561a946ac3b33
parent3d47cd0b46acd2f8b5e71ca572ac46474afbe78e (diff)
downloadcherry-f6b3b95d6fc51e6cc9daf3d51521115ebec039b8.tar.gz
Limit test group and leaf controller updates to that scope.
Change-Id: I50e8b09643c36217c375e18bc99e4e613e5545dd
-rw-r--r--client/js/app.js2
-rw-r--r--client/js/batchResult.js10
-rw-r--r--client/js/services.js93
3 files changed, 81 insertions, 24 deletions
diff --git a/client/js/app.js b/client/js/app.js
index 1a5127c..1dd91d9 100644
--- a/client/js/app.js
+++ b/client/js/app.js
@@ -19,6 +19,8 @@
var debugStr = function(val)
{
var str = JSON.stringify(val);
+ if (str === undefined)
+ return 'undefined';
if (str.length > 100)
return str.slice(0, 97) + "...";
return str;
diff --git a/client/js/batchResult.js b/client/js/batchResult.js
index 9c3509b..7ae04a9 100644
--- a/client/js/batchResult.js
+++ b/client/js/batchResult.js
@@ -235,7 +235,7 @@ angular.module('cherry.batchResult', [])
.controller('TestGroupStatsCtrl', ['$scope', '$stateParams', 'rtdb', 'rpc', function($scope, $stateParams, rtdb, rpc)
{
var objId = $stateParams.batchResultId + '/' + $stateParams.testGroupPath;
- rtdb.bind('TestCaseTreeGroup', objId, $scope);
+ rtdb.bind('TestCaseTreeGroup', objId, $scope, { invalidateMode: 'scope' });
$scope.testGroupPath = $stateParams.testGroupPath;
@@ -304,7 +304,7 @@ angular.module('cherry.batchResult', [])
init: function(objId)
{
- rtdb.bind('TestCaseTreeGroup', objId, $scope);
+ rtdb.bind('TestCaseTreeGroup', objId, $scope, { invalidateMode: 'scope' });
},
getNumResults: function()
@@ -381,11 +381,7 @@ angular.module('cherry.batchResult', [])
// \note obj can be either a header object's id (a string) or the header object itself.
if (_.isString(obj))
{
- // \note object binding is done asynchronously to avoid stalling UI for long (when opening large sub-trees)
- setTimeout(function()
- {
- rtdb.bind('TestCaseHeader', obj, $scope, { onUpdate:onUpdate });
- }, 0);
+ rtdb.bind('TestCaseHeader', obj, $scope, { onUpdate: onUpdate, invalidateMode: 'scope' });
}
else
{
diff --git a/client/js/services.js b/client/js/services.js
index 08cd25a..89e8c93 100644
--- a/client/js/services.js
+++ b/client/js/services.js
@@ -65,19 +65,12 @@ angular.module('cherry.services', [])
var flushInMsgs = function(items)
{
- // \note scope.$apply is wrapped in setTimeout to avoid calling it while angular's digest is already active.
- setTimeout(function()
+ for (var msgNdx = 0; msgNdx < items.length; msgNdx++)
{
- $rootScope.$apply(function ()
- {
- for (var msgNdx = 0; msgNdx < items.length; msgNdx++)
- {
- var msgArgs = items[msgNdx];
- for (var ndx = 0; ndx < msgHandlers.length; ndx++)
- msgHandlers[ndx].call(null, socket, msgArgs); // \todo [petri] this?
- }
- });
- }, 0);
+ var msgArgs = items[msgNdx];
+ for (var ndx = 0; ndx < msgHandlers.length; ndx++)
+ msgHandlers[ndx].call(null, socket, msgArgs); // \todo [petri] this?
+ }
};
var inMsgQueue = new BatchQueue(flushInMsgs, 100);
@@ -277,7 +270,7 @@ angular.module('cherry.services', [])
};
}])
-.factory('rtdb', ['socket', 'rpc', function(socket, rpc)
+.factory('rtdb', ['$rootScope', 'socket', 'rpc', function($rootScope, socket, rpc)
{
console.log('[rtdb] init');
var subscribedObjects = {}; // objectKey(objType, objId): {count:<int>, obj:<obj>}
@@ -612,10 +605,64 @@ angular.module('cherry.services', [])
versionViewedObjectGetQueue.enqueue({ view: view, objType: objType, objId: objId, onUpdate: onUpdate });
};
+ var applyBoundDataUpdates = function(items)
+ {
+ for (var ndx = 0; ndx < items.length; ++ndx)
+ {
+ var scope = items[ndx].scope;
+ var valueName = items[ndx].valueName;
+ var value = items[ndx].value;
+ var onUpdateCb = items[ndx].onUpdateCb;
+ var objType = items[ndx].objType;
+ var objId = items[ndx].objId;
+
+ scope[valueName] = value;
+ if (onUpdateCb)
+ onUpdateCb(objType, objId, value);
+ }
+ };
+
+ var flushRootInvalidateUpdates = function(items)
+ {
+ applyBoundDataUpdates(items);
+ $rootScope.$digest();
+ };
+ var flushScopeInvalidateUpdates = function(items)
+ {
+ applyBoundDataUpdates(items);
+
+ // apply in order
+
+ var scopeList = [];
+ for (var itemNdx = 0; itemNdx < items.length; ++itemNdx)
+ {
+ var seenScope = false;
+ for (var scopeNdx = 0; scopeNdx < scopeList.length; ++scopeNdx)
+ {
+ if (scopeList[scopeNdx] === items[itemNdx].scope)
+ {
+ seenScope = true;
+ break;
+ }
+ }
+
+ if (!seenScope)
+ scopeList.push(items[itemNdx].scope);
+ }
+
+ for (var ndx = 0; ndx < scopeList.length; ++ndx)
+ scopeList[ndx].$digest();
+ };
+
+ var rootInvalidateUpdateQueue = new BatchQueue(flushRootInvalidateUpdates, 10);
+ var scopeInvalidateUpdateQueue = new BatchQueue(flushScopeInvalidateUpdates, 20);
+
var bind = function(objType, objId, scope, options)
{
options = options || {};
var valueName = options.valueName || 'value';
+ var invalidateMode = options.invalidateMode || 'root';
+ var onUpdateCb = options.onUpdate || null;
var initial = {};
initial[valueName] = null;
@@ -623,10 +670,22 @@ angular.module('cherry.services', [])
var onUpdate = function(obj)
{
- scope[valueName] = obj;
-
- if (options.onUpdate)
- options.onUpdate(objType, objId, obj);
+ if (invalidateMode === "root")
+ {
+ rootInvalidateUpdateQueue.enqueue({ scope: scope, valueName: valueName, value: obj, objType: objType, objId: objId, onUpdateCb: onUpdateCb });
+ }
+ else if (invalidateMode === "scope")
+ {
+ scopeInvalidateUpdateQueue.enqueue({ scope: scope, valueName: valueName, value: obj, objType: objType, objId: objId, onUpdateCb: onUpdateCb });
+ }
+ else if (invalidateMode === "none")
+ {
+ scope[valueName] = obj;
+ if (onUpdateCb)
+ onUpdateCb(objType, objId, obj);
+ }
+ else
+ throw "Invalid mode: " + debugStr(invalidateMode);
};
if (scope.rtdbVersionView && scope.rtdbVersionView.id !== undefined)