Introduce internal API call queuing mechanism #43

Merged
laurynas-karvelis merged 2 commits from master into master 2018-03-21 14:59:55 +00:00

View File

@ -1,6 +1,17 @@
// API methods // API methods
import fetch from './fetch'; import fetch from './fetch';
/**
* Simple replacement for Bluebird's Promise.mapSeries() implementation
* @param {Array} tasks to run serially
* @param {Function} task function to execute
* @return {Promise}
*/
function sequence(tasks, fn) {
return tasks.reduce((promise, task) => promise.then(() => fn(task)), Promise.resolve());
}
/** /**
* API class, has a function for each method of the Telegram API which take * API class, has a function for each method of the Telegram API which take
* an object argument, and send request to the API server * an object argument, and send request to the API server
@ -8,6 +19,7 @@ import fetch from './fetch';
* Methods: getMe, sendMessage, forwardMessage, sendPhoto, sendAudio, * Methods: getMe, sendMessage, forwardMessage, sendPhoto, sendAudio,
* sendDocument, sendSticker, sendVideo, sendLocation, sendChatAction, * sendDocument, sendSticker, sendVideo, sendLocation, sendChatAction,
* getUserProfilePhotos, getUpdates * getUserProfilePhotos, getUpdates
*
*/ */
export default class API { export default class API {
/** /**
@ -16,6 +28,29 @@ export default class API {
*/ */
constructor(token) { constructor(token) {
this.token = token; this.token = token;
this._queue = [];
this._inUseQueue = [];
}
/**
* Run Telegram API calls serially using internal queueing mechanism
* @private
*/
_runQueue() {
// implementation taken from https://github.com/yagop/node-telegram-bot-api/issues/192#issuecomment-249488807
if (this._inUseQueue.length || !this._queue.length) return;
this._inUseQueue = this._queue;
this._queue = [];
sequence(this._inUseQueue, request => { //eslint-disable-line
return this.request(request.method, request.data)
.then(request.resolve)
.catch(request.reject);
}).then(() => {
this._inUseQueue = [];
this._runQueue();
});
} }
} }
@ -24,12 +59,16 @@ API.prototype.request = function request(method, data) {
}; };
const methods = ['getMe', 'sendMessage', 'forwardMessage', 'sendPhoto', const methods = ['getMe', 'sendMessage', 'forwardMessage', 'sendPhoto',
'sendAudio', 'sendDocument', 'sendSticker', 'sendVideo', 'sendAudio', 'sendDocument', 'sendSticker', 'sendVideo',
'sendLocation', 'sendChatAction', 'getUserProfilePhotos', 'sendLocation', 'sendChatAction', 'getUserProfilePhotos',
'getUpdates', 'setWebhook', 'deleteMessage']; 'getUpdates', 'setWebhook', 'deleteMessage'];
methods.forEach(method => { methods.forEach(method => {
API.prototype[method] = function(data) { //eslint-disable-line API.prototype[method] = function (data) { //eslint-disable-line
return this.request(method, data); // implementation taken from https://github.com/yagop/node-telegram-bot-api/issues/192#issuecomment-249488807
return new Promise((resolve, reject) => {
this._queue.push({ method, data, resolve, reject });
process.nextTick(this._runQueue.bind(this));
});
}; };
}); });