Backend: implement MemoryCacheProvider (#1613)

While so far tests haven't required this (by mocking), there are
scripts like plugins/github/bin/fetchAndPrintGithubRepo.js which
create a tmp directory as a single-use cache. Here we'll be able
to use the MemoryCacheProvider instead.

In future PRs we'll switch to an API which only accepts CacheProviders.
So having MemoryCacheProvider in place will provide a good alternative
to creating tmp directories.
This commit is contained in:
Robin van Boven 2020-02-03 23:36:58 +01:00 committed by GitHub
parent f22b6a539f
commit 6904621646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 0 deletions

View File

@ -0,0 +1,31 @@
// @flow
import Database from "better-sqlite3";
import {type CacheProvider} from "./cache";
/**
* An in-memory CacheProvider.
*
* Using the same ID's will produce the same cache, however data will be lost when
* the process exits, or references to the MemoryCacheProvider are deleted.
*
* Useful for tests or less I/O intense commands which should run in isolation.
*/
export class MemoryCacheProvider implements CacheProvider {
+_instances: Map<string, Database> = new Map();
/**
* Returns a Database handle associated with this `id`,
* an existing Database from the cache *may* be provided.
*
* Note: the exact Database object may be shared within the process.
*/
async database(id: string): Promise<Database> {
let db = this._instances.get(id);
if (!db) {
db = new Database(":memory:");
this._instances.set(id, db);
}
return db;
}
}

View File

@ -0,0 +1,46 @@
// @flow
import {MemoryCacheProvider} from "./memoryCacheProvider";
import {type CacheProvider} from "./cache";
describe("src/backend/memoryCacheProvider", () => {
describe("MemoryCacheProvider", () => {
it("should be a CacheProvider", () => {
const _ = (x: MemoryCacheProvider): CacheProvider => x;
});
describe("database", () => {
it("should share the Database given the same id", async () => {
// Given
const idA = "alpha";
const idB = "beta";
// When
const cache = new MemoryCacheProvider();
const a1 = await cache.database(idA);
const a2 = await cache.database(idA);
const b1 = await cache.database(idB);
const b2 = await cache.database(idB);
// Then
expect(a1).toBe(a2);
expect(b1).toBe(b2);
expect(a1).not.toBe(b1);
});
it("should not globally share Database given the same id", async () => {
// Given
const id = "alpha";
// When
const cache1 = new MemoryCacheProvider();
const cache2 = new MemoryCacheProvider();
const a1 = await cache1.database(id);
const a2 = await cache2.database(id);
// Then
expect(a1).not.toBe(a2);
});
});
});
});