Skip to content

Commit

Permalink
Typescriptify ClientRequestCache
Browse files Browse the repository at this point in the history
  • Loading branch information
Half-Shot committed Aug 20, 2020
1 parent 49ba2d0 commit f67b310
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 32 deletions.
1 change: 1 addition & 0 deletions changelog.d/204.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Typescriptify ClientRequestCache
2 changes: 1 addition & 1 deletion spec/unit/client-request-cache.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const ClientRequestCache = require("../../lib/components/client-request-cache");
const { ClientRequestCache } = require("../../lib/components/client-request-cache");
const Bluebird = require("bluebird");

describe("ClientRequestCache", function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,58 +17,59 @@ limitations under the License.
/**
* Caches requests in memory and handles expiring them.
*/
class ClientRequestCache {
export class ClientRequestCache<T> {
private requestContent = new Map<string, {ts: number, content: T}>();
/**
* @param ttl {Number} How old a result can be before it gets expired.
* @param size {Number} How many results to store before we trim.
* @param ttl How old a result can be before it gets expired.
* @param size How many results to store before we trim.
* @param requestFunc The function to use on cache miss.
*/
constructor (ttl, size, requestFunc) {
constructor (private readonly ttl: number,
private readonly maxSize: number,
private readonly requestFunc: (...args: any[]) => Promise<T>) {
if (!Number.isInteger(ttl) || ttl <= 0) {
throw Error("'ttl' must be greater than 0");
}
if (!Number.isInteger(size) || ttl <= 0) {
if (!Number.isInteger(maxSize) || ttl <= 0) {
throw Error("'size' must be greater than 0");
}
if (typeof(requestFunc) !== "function") {
throw Error("'requestFunc' must be a function");
}
this._requestContent = new Map(); // key => {ts, content}
this.requestFunc = requestFunc;
this.ttl = ttl;
this.maxSize = size;
}

/**
* Gets a result of a request from the cache, or otherwise
* tries to fetch the the result with this.requestFunc
*
* @param {string}} key Key of the item to get/store.
* @param {any[]} args A set of arguments to pass to the request func.
* @param key Key of the item to get/store.
* @param args A set of arguments to pass to the request func.
* @returns {Promise} The request, or undefined if not retrievable.
* @throws {Error} If the key is not a string.
*/
get(key, ...args) {
get(key: string, ...args: any[]) {
if (typeof(key) !== "string") {
throw Error("'key' must be a string");
}
const cachedResult = this._requestContent.get(key);
const cachedResult = this.requestContent.get(key);
if (cachedResult !== undefined && cachedResult.ts >= Date.now() - this.ttl) {
return cachedResult.content;
}
// Delete the old req.
this._requestContent.delete(key);
return new Promise((resolve, reject) => {
resolve(this.requestFunc.apply(null, [key].concat(args)))
this.requestContent.delete(key);
return new Promise<T>((resolve) => {
resolve(this.requestFunc.apply(null, [key, ...args]))
}).then((result) => {
if (result !== undefined) {
this._requestContent.set(key, {
this.requestContent.set(key, {
ts: Date.now(),
content: result,
});
if (this._requestContent.size > this.maxSize) {
const oldKey = this._requestContent.keys().next().value;
this._requestContent.delete(oldKey);
if (this.requestContent.size > this.maxSize) {
const oldKey = this.requestContent.keys().next().value;
this.requestContent.delete(oldKey);
}
}
return result;
Expand All @@ -82,14 +83,6 @@ class ClientRequestCache {
* @returns {Map<string,any>}
*/
getCachedResults() {
return new Map(this._requestContent);
return new Map(this.requestContent);
}

/**
* @callback requestFunc
* @param {any[]} args A set of arguments passed from get().
* @param {string} key The key for the cached item.
*/
}

module.exports = ClientRequestCache;
8 changes: 4 additions & 4 deletions src/components/intent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import JsSdk from "matrix-js-sdk";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { MatrixEvent, RoomMember } = JsSdk as any;
import ClientRequestCache from "./client-request-cache";
import { ClientRequestCache } from "./client-request-cache";
import { defer } from "../utils/promiseutil";


Expand Down Expand Up @@ -82,9 +82,9 @@ type PowerLevelContent = {

export class Intent {
private _requestCaches: {
profile: ClientRequestCache,
roomstate: ClientRequestCache,
event: ClientRequestCache
profile: ClientRequestCache<any>,
roomstate: ClientRequestCache<any>,
event: ClientRequestCache<any>
}
private opts: {
backingStore: BackingStore,
Expand Down

0 comments on commit f67b310

Please sign in to comment.