foobot-graphql
Version:
GraphQL server for Foobot device data.
198 lines (158 loc) • 5.92 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _map = require('babel-runtime/core-js/map');
var _map2 = _interopRequireDefault(_map);
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _util = require('util');
var _util2 = _interopRequireDefault(_util);
var _humanizeDuration = require('humanize-duration');
var _humanizeDuration2 = _interopRequireDefault(_humanizeDuration);
var _events = require('events');
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* By default, DataLoader caches keys forever. This is not ideal for the types
* of requests we make to the API. For example, we want to be able to tell the
* cache to expire datapoint results five minutes after the last datapoint,
* since that's how often the API updates. Use this with DataLoader's `cacheMap`
* option.
*/
var debug = require('debug')('foobot-graphql:expiring-map');
function formatKey(key) {
return _util2.default.inspect(key, { breakLength: Infinity });
}
var ExpiringMap = function (_EventEmitter) {
(0, _inherits3.default)(ExpiringMap, _EventEmitter);
function ExpiringMap() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var iterable = arguments[1];
(0, _classCallCheck3.default)(this, ExpiringMap);
var _this = (0, _possibleConstructorReturn3.default)(this, (ExpiringMap.__proto__ || (0, _getPrototypeOf2.default)(ExpiringMap)).call(this));
_this.ttl = options.ttl;
_this.map = new _map2.default(iterable);
_this.ids = new _map2.default();
_this.timeouts = new _map2.default();
_this.has = _this.map.has.bind(_this.map);
_this.get = _this.map.get.bind(_this.map);
_this.entries = _this.map.entries.bind(_this.map);
_this.forEach = _this.map.forEach.bind(_this.map);
_this.keys = _this.map.keys.bind(_this.map);
_this.values = _this.map.values.bind(_this.map);
return _this;
}
(0, _createClass3.default)(ExpiringMap, [{
key: 'clear',
value: function clear() {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(this.timeouts.keys()), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
this.clearTimeout(key);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
this.ids.clear();
this.map.clear();
}
}, {
key: 'clearTimeout',
value: function (_clearTimeout) {
function clearTimeout(_x) {
return _clearTimeout.apply(this, arguments);
}
clearTimeout.toString = function () {
return _clearTimeout.toString();
};
return clearTimeout;
}(function (key) {
var timeout = this.timeouts.get(key);
if (timeout) {
debug('Clearing timeout. key=' + formatKey(key));
clearTimeout(timeout);
}
this.timeouts.delete(key);
})
}, {
key: 'delete',
value: function _delete(key) {
this.clearTimeout(key);
this.ids.delete(key);
return this.map.delete(key);
}
}, {
key: 'expire',
value: function expire(key, id) {
if (this.ids.get(key) === id) {
var value = this.get(key);
this.delete(key);
debug('Expired value. key=' + formatKey(key) + '.');
this.emit('expire', key, value);
}
}
}, {
key: 'set',
value: function set(key, value) {
var _this2 = this;
var id = _uuid2.default.v4();
this.ids.set(key, id);
this.map.set(key, value);
this.clearTimeout(key);
var ttl = this.ttl;
if (typeof ttl === 'function') {
ttl = ttl(key, value);
}
if (ttl != null) {
_promise2.default.resolve(ttl).then(function (ttl) {
// Make sure we still care about expiring this particular value by
// checking whether the ID is still the same.
if (ttl != null && _this2.ids.get(key) === id) {
var expire = function expire() {
_this2.expire(key, id);
};
var timeout = setTimeout(expire, ttl);
_this2.timeouts.set(key, timeout);
debug('Expiration set to ' + (0, _humanizeDuration2.default)(ttl) + '. key=' + formatKey(key));
}
});
}
return this;
}
}, {
key: 'size',
get: function get() {
return this.map.size;
}
}]);
return ExpiringMap;
}(_events.EventEmitter);
exports.default = ExpiringMap;