@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Multiplex AJAX calls

Summary: Fixes T5344. Essentially, we only make the AJAX request to `/notification/individual/` if we are the leader tab (i.e. only one tab will make this request). Once a response has been received from the server (containing the contents of the notification), we broadcast the message contents back to all other tabs for rendering.

Test Plan:
Opened two tabs on `/notification/status/` and clicked "Send Test Notification".

**Before**
```lang=bash, name=tail -f /var/log/phabricator-access.log | grep /notification/individual/
[Tue, 13 Jan 2015 20:10:37 +1100] 17033 phabricator 10.0.0.1 josh PhabricatorNotificationIndividualController - /notification/individual/-200 236036
[Tue, 13 Jan 2015 20:10:37 +1100] 17657 phabricator 10.0.0.1 josh PhabricatorNotificationIndividualController - /notification/individual/-200 24130
```

**After**
```lang=bash, name=tail -f /var/log/phabricator-access.log | grep /notification/individual/
[Tue, 13 Jan 2015 20:11:15 +1100] 17657 phabricator 10.0.0.1 josh PhabricatorNotificationIndividualController - /notification/individual/-200 180217
```

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T5344

Differential Revision: https://secure.phabricator.com/D11360

+69 -49
+34 -33
resources/celerity/map.php
··· 8 8 return array( 9 9 'names' => array( 10 10 'core.pkg.css' => '8d1c0f87', 11 - 'core.pkg.js' => 'b6a9c22a', 11 + 'core.pkg.js' => '7923c2e6', 12 12 'darkconsole.pkg.js' => '8ab24e01', 13 13 'differential.pkg.css' => '8af45893', 14 14 'differential.pkg.js' => 'dad3622f', ··· 342 342 'rsrc/image/texture/table_header.png' => '5c433037', 343 343 'rsrc/image/texture/table_header_hover.png' => '038ec3b9', 344 344 'rsrc/image/texture/table_header_tall.png' => 'd56b434f', 345 - 'rsrc/js/application/aphlict/Aphlict.js' => 'b300dac3', 345 + 'rsrc/js/application/aphlict/Aphlict.js' => '2be71d56', 346 346 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '335470d7', 347 - 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '62998733', 347 + 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '851f167c', 348 348 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'ea681761', 349 349 'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18', 350 350 'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de', 351 351 'rsrc/js/application/conpherence/behavior-menu.js' => 'f0a41b9f', 352 - 'rsrc/js/application/conpherence/behavior-pontificate.js' => 'e23dfe0f', 352 + 'rsrc/js/application/conpherence/behavior-pontificate.js' => '2f6efe18', 353 353 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '40b1ff90', 354 354 'rsrc/js/application/countdown/timer.js' => 'e4cc26b3', 355 355 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e', ··· 535 535 'herald-rule-editor' => '335fd41f', 536 536 'herald-test-css' => '778b008e', 537 537 'inline-comment-summary-css' => '8cfd34e8', 538 - 'javelin-aphlict' => 'b300dac3', 538 + 'javelin-aphlict' => '2be71d56', 539 539 'javelin-behavior' => '61cbc29a', 540 540 'javelin-behavior-aphlict-dropdown' => '335470d7', 541 - 'javelin-behavior-aphlict-listen' => '62998733', 541 + 'javelin-behavior-aphlict-listen' => '851f167c', 542 542 'javelin-behavior-aphlict-status' => 'ea681761', 543 543 'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884', 544 544 'javelin-behavior-aphront-crop' => 'fa0f4fc2', ··· 552 552 'javelin-behavior-choose-control' => '6153c708', 553 553 'javelin-behavior-config-reorder-fields' => '14a827de', 554 554 'javelin-behavior-conpherence-menu' => 'f0a41b9f', 555 - 'javelin-behavior-conpherence-pontificate' => 'e23dfe0f', 555 + 'javelin-behavior-conpherence-pontificate' => '2f6efe18', 556 556 'javelin-behavior-conpherence-widget-pane' => '40b1ff90', 557 557 'javelin-behavior-countdown-timer' => 'e4cc26b3', 558 558 'javelin-behavior-dark-console' => '08883e8b', ··· 975 975 'javelin-install', 976 976 'javelin-util', 977 977 ), 978 + '2be71d56' => array( 979 + 'javelin-install', 980 + 'javelin-util', 981 + 'javelin-websocket', 982 + 'javelin-leader', 983 + 'javelin-json', 984 + ), 978 985 '2bfa2836' => array( 979 986 'javelin-behavior', 980 987 'javelin-stratcom', ··· 985 992 'javelin-dom', 986 993 'javelin-stratcom', 987 994 'phabricator-keyboard-shortcut', 995 + ), 996 + '2f6efe18' => array( 997 + 'javelin-behavior', 998 + 'javelin-dom', 999 + 'javelin-util', 1000 + 'javelin-workflow', 1001 + 'javelin-stratcom', 988 1002 ), 989 1003 '316b8fa1' => array( 990 1004 'javelin-install', ··· 1212 1226 'javelin-magical-init', 1213 1227 'javelin-util', 1214 1228 ), 1215 - 62998733 => array( 1216 - 'javelin-behavior', 1217 - 'javelin-aphlict', 1218 - 'javelin-stratcom', 1219 - 'javelin-request', 1220 - 'javelin-uri', 1221 - 'javelin-dom', 1222 - 'javelin-json', 1223 - 'javelin-router', 1224 - 'javelin-util', 1225 - 'phabricator-notification', 1226 - ), 1227 1229 '6453c869' => array( 1228 1230 'javelin-install', 1229 1231 'javelin-dom', ··· 1381 1383 'javelin-workflow', 1382 1384 'phabricator-draggable-list', 1383 1385 ), 1386 + '851f167c' => array( 1387 + 'javelin-behavior', 1388 + 'javelin-aphlict', 1389 + 'javelin-stratcom', 1390 + 'javelin-request', 1391 + 'javelin-uri', 1392 + 'javelin-dom', 1393 + 'javelin-json', 1394 + 'javelin-router', 1395 + 'javelin-util', 1396 + 'javelin-leader', 1397 + 'phabricator-notification', 1398 + ), 1384 1399 '85ea0626' => array( 1385 1400 'javelin-install', 1386 1401 ), ··· 1581 1596 'javelin-dom', 1582 1597 'phortune-credit-card-form', 1583 1598 ), 1584 - 'b300dac3' => array( 1585 - 'javelin-install', 1586 - 'javelin-util', 1587 - 'javelin-websocket', 1588 - 'javelin-leader', 1589 - 'javelin-json', 1590 - ), 1591 1599 'b3a4b884' => array( 1592 1600 'javelin-behavior', 1593 1601 'phabricator-prefab', ··· 1776 1784 'javelin-behavior', 1777 1785 'javelin-stratcom', 1778 1786 'javelin-dom', 1779 - ), 1780 - 'e23dfe0f' => array( 1781 - 'javelin-behavior', 1782 - 'javelin-dom', 1783 - 'javelin-util', 1784 - 'javelin-workflow', 1785 - 'javelin-stratcom', 1786 1787 ), 1787 1788 'e32d14ab' => array( 1788 1789 'javelin-behavior',
+2 -2
webroot/rsrc/js/application/aphlict/Aphlict.js
··· 116 116 } 117 117 break; 118 118 119 - case 'aphlict.server': 119 + default: 120 120 var handler = this.getHandler(); 121 - handler && handler(message.data); 121 + handler && handler(message); 122 122 break; 123 123 } 124 124 },
+32 -13
webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js
··· 9 9 * javelin-json 10 10 * javelin-router 11 11 * javelin-util 12 + * javelin-leader 12 13 * phabricator-notification 13 14 */ 14 15 15 16 JX.behavior('aphlict-listen', function(config) { 16 17 var showing_reload = false; 17 18 18 - JX.Stratcom.listen('aphlict-receive-message', null, function(e) { 19 + JX.Stratcom.listen('aphlict-server-message', null, function(e) { 19 20 var message = e.getData(); 20 21 21 22 if (message.type != 'notification') { 22 23 return; 23 24 } 24 25 25 - var request = new JX.Request( 26 - '/notification/individual/', 27 - onNotification); 26 + JX.Leader.callIfLeader(function() { 27 + var request = new JX.Request( 28 + '/notification/individual/', 29 + onNotification); 28 30 29 - var routable = request 30 - .addData({key: message.key}) 31 - .getRoutable(); 31 + var routable = request 32 + .addData({key: message.key}) 33 + .getRoutable(); 32 34 33 - routable 34 - .setType('notification') 35 - .setPriority(250); 35 + routable 36 + .setType('notification') 37 + .setPriority(250); 36 38 37 - JX.Router.getInstance().queue(routable); 39 + JX.Router.getInstance().queue(routable); 40 + }); 38 41 }); 39 42 40 43 // Respond to a notification from the Aphlict notification server. We send 41 44 // a request to Phabricator to get notification details. 42 45 function onAphlictMessage(message) { 43 - JX.Stratcom.invoke('aphlict-receive-message', null, message); 46 + switch (message.type) { 47 + case 'aphlict.server': 48 + JX.Stratcom.invoke('aphlict-server-message', null, message.data); 49 + break; 50 + 51 + case 'notification.individual': 52 + JX.Stratcom.invoke('aphlict-notification-message', null, message.data); 53 + break; 54 + } 44 55 } 45 56 46 57 // Respond to a response from Phabricator about a specific notification. ··· 49 60 return; 50 61 } 51 62 63 + JX.Leader.broadcast(null, { 64 + type: 'notification.individual', 65 + data: response 66 + }); 67 + } 68 + 69 + JX.Stratcom.listen('aphlict-notification-message', null, function(e) { 52 70 JX.Stratcom.invoke('notification-panel-update', null, {}); 71 + var response = e.getData(); 53 72 54 73 // Show the notification itself. 55 74 new JX.Notification() ··· 68 87 69 88 showing_reload = true; 70 89 } 71 - } 90 + }); 72 91 73 92 var client = new JX.Aphlict( 74 93 config.websocketURI,
+1 -1
webroot/rsrc/js/application/conpherence/behavior-pontificate.js
··· 33 33 infonode.value = id; 34 34 } 35 35 36 - JX.Stratcom.listen('aphlict-receive-message', null, function(e) { 36 + JX.Stratcom.listen('aphlict-server-message', null, function(e) { 37 37 var message = e.getData(); 38 38 39 39 if (message.type != 'message') {