CartoDB/cartodb20

View on GitHub
lib/assets/javascripts/dashboard/data/background-polling/poller.js

Summary

Maintainability
C
1 day
Test Coverage
const _ = require('underscore');
/*
 * Periodically fetches a model/collection. It waits for ongoing
 * fetch requests before trying to fetch again. A stop condition
 * can be specified.
 *
 * Usage example:
 *
 * var poller = new Poller(model, {
 *   interval: 1000,
 *   stopWhen: function (model) {
 *     return model.get('state') === 'completed';
 *   }
 * });
 *
 * poller.start();
 *
 * // ...
 *
 * poller.stop();
 *
 */
const Poller = function (model, options) {
  this.model = model;
  this.numberOfRequests = 0;
  this.polling = false;
  this.interval = options['interval'];

  if (typeof this.interval !== 'function') {
    this.interval = function () { return options['interval']; };
  }

  this.stopWhen = options['stopWhen'];
  this.error = options['error'];
  this.autoStart = options['autoStart'];

  if (this.autoStart) {
    this.start();
  }
};

Poller.prototype.start = function () {
  if (this.timeout) {
    return;
  }

  this._scheduleFetch();
};

Poller.prototype._scheduleFetch = function () {
  this.timeout = setTimeout(this._fetch.bind(this), this.interval(this.numberOfRequests));
};

Poller.prototype._fetch = function () {
  if (!this.polling) {
    this.polling = true;
    this.model.fetch({
      success: () => {
        this.polling = false;
        this.numberOfRequests++;
        if (this._continuePolling()) {
          this._scheduleFetch();
        }
      },
      error: (e) => {
        _.isFunction(this.error) && this.error(this.model);
      }
    });
  }
};

Poller.prototype._continuePolling = function () {
  return !this.stopWhen ||
    (_.isFunction(this.stopWhen) && !this.stopWhen(this.model));
};

Poller.prototype.stop = function () {
  this.polling = false;
  clearTimeout(this.timeout);
  delete this.timeout;
};

module.exports = Poller;