mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-23 23:44:53 +00:00
Merge "Add a PromisePrioritizer and use it for notifications fetching"
This commit is contained in:
commit
1cca7453b3
|
@ -196,6 +196,7 @@ $wgResourceModules += array(
|
|||
'ext.echo.api' => $echoResourceTemplate + array(
|
||||
'scripts' => array(
|
||||
'api/mw.echo.api.js',
|
||||
'api/mw.echo.api.PromisePrioritizer.js',
|
||||
'api/mw.echo.api.EchoApi.js',
|
||||
'api/mw.echo.api.APIHandler.js',
|
||||
'api/mw.echo.api.LocalAPIHandler.js',
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
this.fetchingPromise = null;
|
||||
this.limit = config.limit || 25;
|
||||
this.fetchingPrioritizer = new mw.echo.api.PromisePrioritizer();
|
||||
};
|
||||
|
||||
OO.initClass( mw.echo.api.EchoApi );
|
||||
|
@ -147,13 +148,13 @@
|
|||
return $.Deferred().reject().promise();
|
||||
}
|
||||
|
||||
return handler.fetchNotifications(
|
||||
return this.fetchingPrioritizer.prioritize( handler.fetchNotifications(
|
||||
type,
|
||||
// For the remote source, we are fetching 'local' notifications
|
||||
'local',
|
||||
!!isForced,
|
||||
this.convertFiltersToAPIParams( filters )
|
||||
)
|
||||
) )
|
||||
.then( function ( result ) {
|
||||
return OO.getProp( result.query, 'notifications' );
|
||||
} );
|
||||
|
@ -177,12 +178,12 @@
|
|||
[ sources ] :
|
||||
'local';
|
||||
|
||||
return this.network.getApiHandler( 'local' ).fetchNotifications(
|
||||
return this.fetchingPrioritizer.prioritize( this.network.getApiHandler( 'local' ).fetchNotifications(
|
||||
type,
|
||||
sources,
|
||||
isForced,
|
||||
this.convertFiltersToAPIParams( filters )
|
||||
)
|
||||
) )
|
||||
.then( function ( result ) {
|
||||
return OO.getProp( result.query, 'notifications' );
|
||||
} );
|
||||
|
|
88
modules/api/mw.echo.api.PromisePrioritizer.js
Normal file
88
modules/api/mw.echo.api.PromisePrioritizer.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
( function ( mw, $ ) {
|
||||
/**
|
||||
* Promise prioritizer for API actions. The prioritizer takes
|
||||
* a promise at a time, always prioritizing the latest promise and
|
||||
* aborting and ignoring the others.
|
||||
*
|
||||
* This allows us to send multiple promises in quick successions but
|
||||
* trust that we get back only the latest successful request.
|
||||
*
|
||||
* @class
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
mw.echo.api.PromisePrioritizer = function MwEchoApiPromisePrioritizer() {
|
||||
this.deferred = $.Deferred();
|
||||
this.promise = null;
|
||||
};
|
||||
|
||||
/* Initialization */
|
||||
|
||||
OO.initClass( mw.echo.api.PromisePrioritizer );
|
||||
|
||||
/**
|
||||
* Prioritize a promise
|
||||
*
|
||||
* @param {jQuery.Promise|Promise} promise Promise
|
||||
* @return {jQuery.Promise} The main deferred object that resolves
|
||||
* or rejects when the latest promise is resolved or rejected.
|
||||
*/
|
||||
mw.echo.api.PromisePrioritizer.prototype.prioritize = function ( promise ) {
|
||||
var previousPromise = this.promise;
|
||||
|
||||
promise
|
||||
.then(
|
||||
this.setSuccess.bind( this, promise ),
|
||||
this.setFailure.bind( this, promise )
|
||||
);
|
||||
this.promise = promise;
|
||||
|
||||
if ( previousPromise && previousPromise.abort ) {
|
||||
previousPromise.abort();
|
||||
}
|
||||
|
||||
return this.deferred.promise();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set success for the promise. Resolve the main deferred object only
|
||||
* if we are dealing with the currently prioritized promise.
|
||||
*
|
||||
* @param {jQuery.Promise} promise The promise that resolved successfully.
|
||||
* The main deferred object is resolved with the result of the
|
||||
* latest prioritized promise.
|
||||
*/
|
||||
mw.echo.api.PromisePrioritizer.prototype.setSuccess = function ( promise ) {
|
||||
var prioritizer = this;
|
||||
|
||||
if ( this.promise === promise ) {
|
||||
this.promise.done( function () {
|
||||
prioritizer.deferred.resolve.apply( prioritizer.deferred, arguments );
|
||||
|
||||
prioritizer.promise = null;
|
||||
prioritizer.deferred = $.Deferred();
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set failure for the promise. Reject the main deferred object only
|
||||
* if we are dealing with the currently prioritized promise.
|
||||
*
|
||||
* @param {jQuery.Promise} promise The promise that failed.
|
||||
* The main deferred object is rejected with the result of the
|
||||
* latest prioritized promise
|
||||
*/
|
||||
mw.echo.api.PromisePrioritizer.prototype.setFailure = function ( promise ) {
|
||||
var prioritizer = this;
|
||||
|
||||
if ( this.promise === promise ) {
|
||||
this.promise.fail( function () {
|
||||
prioritizer.deferred.reject.apply( prioritizer.deferred, arguments );
|
||||
|
||||
prioritizer.promise = null;
|
||||
prioritizer.deferred = $.Deferred();
|
||||
} );
|
||||
}
|
||||
};
|
||||
} )( mediaWiki, jQuery );
|
|
@ -205,7 +205,6 @@
|
|||
*/
|
||||
mw.echo.ui.NotificationsInboxWidget.prototype.pushPending = function () {
|
||||
this.noticeMessageWidget.toggle( false );
|
||||
this.readStateSelectWidget.setDisabled( true );
|
||||
this.topPaginationWidget.setDisabled( true );
|
||||
this.bottomPaginationWidget.setDisabled( true );
|
||||
|
||||
|
@ -218,7 +217,6 @@
|
|||
*/
|
||||
mw.echo.ui.NotificationsInboxWidget.prototype.popPending = function () {
|
||||
this.resetMessageLabel();
|
||||
this.readStateSelectWidget.setDisabled( false );
|
||||
this.topPaginationWidget.setDisabled( false );
|
||||
this.bottomPaginationWidget.setDisabled( false );
|
||||
|
||||
|
|
Loading…
Reference in a new issue