mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-09 16:32:39 +01:00
When updating a workboard with "R", send the client visible set with version numbers
Summary: Depends on D20652. Ref T4900. When the user presses "R", send a list of cards currently visible on the client and their version numbers. On the server: - Compare the client verisons to the server versions so we can skip updates for objects which have not changed. (For now, the client version is always "1" and the server version is always "2", so this doesn't do anything meaningful, and every card is always updated.) - Compare the client visible set to the server visible set and "remove" any cards which have been removed from the board. I believe this means that "R" always puts the board into the right state (except for some issues with client orderings not being fully handled yet). It's not tremendously efficient, but we can make versioning better (using the largest object transaction ID) to improve that and loading the page in the first place doesn't take all that long so even sending down the full visible set shouldn't be a huge problem. Test Plan: - In window A, removed a card from a board. - In window B, pressed "R" and saw the removal reflected on the client. - (Also added cards, edited cards, etc., and didn't catch anything exploding.) Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T4900 Differential Revision: https://secure.phabricator.com/D20653
This commit is contained in:
parent
1ee6ecf397
commit
8669c3c0d2
4 changed files with 69 additions and 22 deletions
|
@ -412,9 +412,9 @@ return array(
|
||||||
'rsrc/js/application/phortune/phortune-credit-card-form.js' => 'd12d214f',
|
'rsrc/js/application/phortune/phortune-credit-card-form.js' => 'd12d214f',
|
||||||
'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9',
|
'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9',
|
||||||
'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '9347f172',
|
'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '9347f172',
|
||||||
'rsrc/js/application/projects/WorkboardBoard.js' => '46573d65',
|
'rsrc/js/application/projects/WorkboardBoard.js' => '50147a89',
|
||||||
'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8',
|
'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8',
|
||||||
'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4',
|
'rsrc/js/application/projects/WorkboardCardTemplate.js' => '84f82dad',
|
||||||
'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63',
|
'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63',
|
||||||
'rsrc/js/application/projects/WorkboardController.js' => 'b9d0c2f3',
|
'rsrc/js/application/projects/WorkboardController.js' => 'b9d0c2f3',
|
||||||
'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661',
|
'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661',
|
||||||
|
@ -743,9 +743,9 @@ return array(
|
||||||
'javelin-view-renderer' => '9aae2b66',
|
'javelin-view-renderer' => '9aae2b66',
|
||||||
'javelin-view-visitor' => '308f9fe4',
|
'javelin-view-visitor' => '308f9fe4',
|
||||||
'javelin-websocket' => 'fdc13e4e',
|
'javelin-websocket' => 'fdc13e4e',
|
||||||
'javelin-workboard-board' => '46573d65',
|
'javelin-workboard-board' => '50147a89',
|
||||||
'javelin-workboard-card' => '0392a5d8',
|
'javelin-workboard-card' => '0392a5d8',
|
||||||
'javelin-workboard-card-template' => '2a61f8d4',
|
'javelin-workboard-card-template' => '84f82dad',
|
||||||
'javelin-workboard-column' => 'c3d24e63',
|
'javelin-workboard-column' => 'c3d24e63',
|
||||||
'javelin-workboard-controller' => 'b9d0c2f3',
|
'javelin-workboard-controller' => 'b9d0c2f3',
|
||||||
'javelin-workboard-drop-effect' => '8e0aa661',
|
'javelin-workboard-drop-effect' => '8e0aa661',
|
||||||
|
@ -1133,9 +1133,6 @@ return array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
),
|
),
|
||||||
'2a61f8d4' => array(
|
|
||||||
'javelin-install',
|
|
||||||
),
|
|
||||||
'2a8b62d9' => array(
|
'2a8b62d9' => array(
|
||||||
'multirow-row-manager',
|
'multirow-row-manager',
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
|
@ -1292,18 +1289,6 @@ return array(
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
'phabricator-busy',
|
'phabricator-busy',
|
||||||
),
|
),
|
||||||
'46573d65' => array(
|
|
||||||
'javelin-install',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-workflow',
|
|
||||||
'phabricator-draggable-list',
|
|
||||||
'javelin-workboard-column',
|
|
||||||
'javelin-workboard-header-template',
|
|
||||||
'javelin-workboard-card-template',
|
|
||||||
'javelin-workboard-order-template',
|
|
||||||
),
|
|
||||||
'47a0728b' => array(
|
'47a0728b' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1372,6 +1357,18 @@ return array(
|
||||||
'4feea7d3' => array(
|
'4feea7d3' => array(
|
||||||
'trigger-rule-control',
|
'trigger-rule-control',
|
||||||
),
|
),
|
||||||
|
'50147a89' => array(
|
||||||
|
'javelin-install',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-workflow',
|
||||||
|
'phabricator-draggable-list',
|
||||||
|
'javelin-workboard-column',
|
||||||
|
'javelin-workboard-header-template',
|
||||||
|
'javelin-workboard-card-template',
|
||||||
|
'javelin-workboard-order-template',
|
||||||
|
),
|
||||||
'506aa3f4' => array(
|
'506aa3f4' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
|
@ -1619,6 +1616,9 @@ return array(
|
||||||
'javelin-resource',
|
'javelin-resource',
|
||||||
'javelin-routable',
|
'javelin-routable',
|
||||||
),
|
),
|
||||||
|
'84f82dad' => array(
|
||||||
|
'javelin-install',
|
||||||
|
),
|
||||||
'87428eb2' => array(
|
'87428eb2' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-diffusion-locate-file-source',
|
'javelin-diffusion-locate-file-source',
|
||||||
|
|
|
@ -20,13 +20,42 @@ final class PhabricatorProjectBoardReloadController
|
||||||
$board_phid = $project->getPHID();
|
$board_phid = $project->getPHID();
|
||||||
|
|
||||||
$objects = $state->getObjects();
|
$objects = $state->getObjects();
|
||||||
$object_phids = mpull($objects, 'getPHID');
|
$objects = mpull($objects, null, 'getPHID');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$client_state = $request->getStr('state');
|
||||||
|
$client_state = phutil_json_decode($client_state);
|
||||||
|
} catch (PhutilJSONParserException $ex) {
|
||||||
|
$client_state = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out which objects need to be updated: either the client has an
|
||||||
|
// out-of-date version of them (objects which have been edited); or they
|
||||||
|
// exist on the client but not on the server (objects which have been
|
||||||
|
// removed from the board); or they exist on the server but not on the
|
||||||
|
// client (objects which have been added to the board).
|
||||||
|
|
||||||
|
$update_objects = array();
|
||||||
|
foreach ($objects as $object_phid => $object) {
|
||||||
|
|
||||||
|
// TODO: For now, this is always hard-coded.
|
||||||
|
$object_version = 2;
|
||||||
|
|
||||||
|
$client_version = idx($client_state, $object_phid, 0);
|
||||||
|
if ($object_version > $client_version) {
|
||||||
|
$update_objects[$object_phid] = $object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$update_phids = array_keys($update_objects);
|
||||||
|
$visible_phids = array_keys($client_state);
|
||||||
|
|
||||||
$engine = id(new PhabricatorBoardResponseEngine())
|
$engine = id(new PhabricatorBoardResponseEngine())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->setBoardPHID($board_phid)
|
->setBoardPHID($board_phid)
|
||||||
->setObjects($objects)
|
->setObjects($objects)
|
||||||
->setUpdatePHIDs($object_phids);
|
->setUpdatePHIDs($update_phids)
|
||||||
|
->setVisiblePHIDs($visible_phids);
|
||||||
|
|
||||||
// TODO: We don't currently process "order" properly. If a user is viewing
|
// TODO: We don't currently process "order" properly. If a user is viewing
|
||||||
// a board grouped by "Owner", and another user changes a task to be owned
|
// a board grouped by "Owner", and another user changes a task to be owned
|
||||||
|
|
|
@ -734,7 +734,20 @@ JX.install('WorkboardBoard', {
|
||||||
},
|
},
|
||||||
|
|
||||||
_reloadCards: function() {
|
_reloadCards: function() {
|
||||||
var data = {};
|
var state = {};
|
||||||
|
|
||||||
|
var columns = this.getColumns();
|
||||||
|
for (var column_phid in columns) {
|
||||||
|
var cards = columns[column_phid].getCards();
|
||||||
|
for (var card_phid in cards) {
|
||||||
|
state[card_phid] = this.getCardTemplate(card_phid).getVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
state: JX.JSON.stringify(state),
|
||||||
|
};
|
||||||
|
|
||||||
var on_reload = JX.bind(this, this._onReloadResponse);
|
var on_reload = JX.bind(this, this._onReloadResponse);
|
||||||
|
|
||||||
new JX.Request(this.getController().getReloadURI(), on_reload)
|
new JX.Request(this.getController().getReloadURI(), on_reload)
|
||||||
|
|
|
@ -28,6 +28,11 @@ JX.install('WorkboardCardTemplate', {
|
||||||
return this._phid;
|
return this._phid;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getVersion: function() {
|
||||||
|
// TODO: For now, just return a constant version number.
|
||||||
|
return 1;
|
||||||
|
},
|
||||||
|
|
||||||
setNodeHTMLTemplate: function(html) {
|
setNodeHTMLTemplate: function(html) {
|
||||||
this._html = html;
|
this._html = html;
|
||||||
return this;
|
return this;
|
||||||
|
|
Loading…
Reference in a new issue