Force-invoke the background queue after some AJAX requests
authorAlexander Ebert <ebert@woltlab.com>
Thu, 22 Feb 2018 12:16:51 +0000 (13:16 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 22 Feb 2018 12:16:51 +0000 (13:16 +0100)
wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js
wcfsetup/install/files/js/WoltLabSuite/Core/BackgroundQueue.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/BootstrapFrontend.js
wcfsetup/install/files/lib/action/AJAXProxyAction.class.php

index 9e5a23e4de9e0a0a09674287b9f0912499674bf4..7bc424ec795b4a0c27dd2d771472b9509c18f7f1 100644 (file)
@@ -241,6 +241,13 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt
                                        if (data && data.returnValues && data.returnValues.template !== undefined) {
                                                data.returnValues.template = data.returnValues.template.trim();
                                        }
+                                       
+                                       // force-invoke the background queue
+                                       if (data && data.forceBackgroundQueuePerform) {
+                                               require(['WoltLabSuite/Core/BackgroundQueue'], function(BackgroundQueue) {
+                                                       BackgroundQueue.invoke();
+                                               });
+                                       }
                                }
                                
                                options.success(data, xhr.responseText, xhr, options.data);
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/BackgroundQueue.js b/wcfsetup/install/files/js/WoltLabSuite/Core/BackgroundQueue.js
new file mode 100644 (file)
index 0000000..de61eb7
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * Manages the invocation of the background queue.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2018 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLabSuite/Core/BackgroundQueue
+ */
+define(['Ajax'], function(Ajax) {
+       "use strict";
+       
+       var _invocations = 0;
+       var _isBusy = false;
+       var _url = '';
+       
+       /**
+        * @exports     WoltLabSuite/Core/BackgroundQueue
+        */
+       return {
+               /**
+                * Sets the url of the background queue perform action.
+                * 
+                * @param       {string}        url     background queue perform url
+                */
+               setUrl: function (url) {
+                       _url = url;
+               },
+               
+               /**
+                * Invokes the background queue.
+                */
+               invoke: function () {
+                       if (_url === '') {
+                               console.error('The background queue has not been initialized yet.');
+                               return;
+                       }
+                       
+                       if (_isBusy) return;
+                       
+                       _invocations = 0;
+                       _isBusy = true;
+                       
+                       Ajax.api(this);
+               },
+               
+               _ajaxSuccess: function (data) {
+                       _invocations++;
+                       
+                       // invoke the queue up to 5 times in a row
+                       if (data > 0 && _invocations < 5) {
+                               window.setTimeout(this.invoke.bind(this), 1000);
+                       }
+                       else {
+                               _isBusy = false;
+                       }
+               },
+               
+               _ajaxSetup: function () {
+                       return {
+                               url: _url,
+                               ignoreError: true,
+                               silent: true
+                       }
+               }
+       }
+});
\ No newline at end of file
index 801fc597a10dea032f4644a6b8d9833655fc8c6e..9a2b08f90fd0e45519e830dd8fe8d739c64d539f 100644 (file)
@@ -2,24 +2,22 @@
  * Bootstraps WCF's JavaScript with additions for the frontend usage.
  * 
  * @author     Alexander Ebert
- * @copyright  2001-2017 WoltLab GmbH
+ * @copyright  2001-2018 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLabSuite/Core/BootstrapFrontend
  */
 define(
        [
-               'Ajax',                           'WoltLabSuite/Core/Bootstrap',      'WoltLabSuite/Core/Controller/Style/Changer',
+               'WoltLabSuite/Core/BackgroundQueue', 'WoltLabSuite/Core/Bootstrap', 'WoltLabSuite/Core/Controller/Style/Changer',
                'WoltLabSuite/Core/Controller/Popover', 'WoltLabSuite/Core/Ui/User/Ignore', 'WoltLabSuite/Core/Ui/Page/Header/Menu'
        ],
        function(
-               Ajax,                              Bootstrap,                    ControllerStyleChanger,
-               ControllerPopover,                 UiUserIgnore, UiPageHeaderMenu
+               BackgroundQueue, Bootstrap, ControllerStyleChanger,
+               ControllerPopover, UiUserIgnore, UiPageHeaderMenu
        )
 {
        "use strict";
        
-       var queueInvocations = 0;
-       
        /**
         * @exports     WoltLabSuite/Core/BootstrapFrontend
         */
@@ -42,7 +40,12 @@ define(
                        }
                        
                        this._initUserPopover();
-                       this._invokeBackgroundQueue(options.backgroundQueue.url, options.backgroundQueue.force);
+                       
+                       BackgroundQueue.setUrl(options.backgroundQueue.url);
+                       if (Math.random() < 0.1 || options.backgroundQueue.force) {
+                               // invoke the queue roughly every 10th request or on demand
+                               BackgroundQueue.invoke();
+                       }
                        
                        UiUserIgnore.init();
                },
@@ -67,31 +70,6 @@ define(
                                        }, callback, callback);
                                }
                        });
-               },
-               
-               /**
-                * Invokes the background queue roughly every 10th request.
-                * 
-                * @param       {string}        url     background queue url
-                * @param       {boolean}       force   whether execution should be forced
-                */
-               _invokeBackgroundQueue: function(url, force) {
-                       var again = this._invokeBackgroundQueue.bind(this, url, true);
-                       
-                       if (Math.random() < 0.1 || force) {
-                               // 'fire and forget' background queue perform task
-                               Ajax.apiOnce({
-                                       url: url,
-                                       ignoreError: true,
-                                       silent: true,
-                                       success: (function(data) {
-                                               queueInvocations++;
-                                               
-                                               // process up to 5 queue items per page load
-                                               if (data > 0 && queueInvocations < 5) setTimeout(again, 1000);
-                                       }).bind(this)
-                               });
-                       }
                }
        };
 });
index b7e6edfe3f6be2653362180839eb958c48c55cd8..8b22f323f96924654d09844772f225d5ba97174f 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\action;
 use wcf\data\IDatabaseObjectAction;
 use wcf\system\exception\ImplementationException;
 use wcf\system\WCF;
+use wcf\system\WCFACP;
 use wcf\util\ArrayUtil;
 use wcf\util\StringUtil;
 
@@ -95,6 +96,11 @@ class AJAXProxyAction extends AJAXInvokeAction {
                        }
                }
                
+               // force background queue invocation
+               if (!class_exists(WCFACP::class, false) && WCF::getSession()->getVar('forceBackgroundQueuePerform')) {
+                       $this->response['forceBackgroundQueuePerform'] = true;
+               }
+               
                parent::sendResponse();
        }
 }