gecko-dev/devtools/client/memory/actions/task-cache.js
J. Ryan Stinnett 30b2b7ce44 Bug 1271084 - Apply ESLint autofixes to ignored /devtools files. r=tromey
For simple rules like function spacing, we can auto-fix these across the code
base so they are followed in a consistent way.

To generate this patch, I ran:

./mach eslint devtools --no-ignore --fix

After this, I reverted any changes to third party files that we really do want
to ignore.

MozReview-Commit-ID: 6Q8BApkAW20
2016-05-18 12:49:23 -05:00

100 lines
2.5 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { assert } = require("devtools/shared/DevToolsUtils");
/**
* The `TaskCache` allows for re-using active tasks when spawning a second task
* would simply duplicate work and is unnecessary. It maps from a task's unique
* key to the promise of its result.
*/
const TaskCache = module.exports = class TaskCache {
constructor() {
this._cache = new Map();
}
/**
* Get the promise keyed by the given unique `key`, if one exists.
*
* @param {Any} key
* @returns {Promise<Any> | undefined}
*/
get(key) {
return this._cache.get(key);
}
/**
* Put the task result promise in the cache and associate it with the given
* `key` which must not already have an entry in the cache.
*
* @param {Any} key
* @param {Promise<Any>} promise
*/
put(key, promise) {
assert(!this._cache.has(key),
"We should not override extant entries");
this._cache.set(key, promise);
}
/**
* Remove the cache entry with the given key.
*
* @param {Any} key
*/
remove(key) {
assert(this._cache.has(key),
`Should have an extant entry for key = ${key}`);
this._cache.delete(key);
}
};
/**
* Create a new action-orchestrating task that is automatically cached. The
* tasks themselves are responsible from removing themselves from the cache.
*
* @param {Function(...args) -> Any} getCacheKey
* @param {Generator(...args) -> Any} task
*
* @returns Cacheable, Action-Creating Task
*/
TaskCache.declareCacheableTask = function ({ getCacheKey, task }) {
const cache = new TaskCache();
return function (...args) {
return function* (dispatch, getState) {
const key = getCacheKey(...args);
const extantResult = cache.get(key);
if (extantResult) {
return extantResult;
}
// Ensure that we have our new entry in the cache *before* dispatching the
// task!
let resolve;
cache.put(key, new Promise(r => {
resolve = r;
}));
resolve(dispatch(function* () {
try {
args.push(() => cache.remove(key), dispatch, getState);
return yield* task(...args);
} catch (error) {
// Don't perma-cache errors.
if (cache.get(key)) {
cache.remove(key);
}
throw error;
}
}));
return yield cache.get(key);
};
};
};