Studentify database clients and website API adapters
This commit is contained in:
parent
9c719b96b3
commit
a35e6a99cb
@ -10,13 +10,6 @@ const arangoKv = arango.collection("kv");
|
||||
|
||||
type Timing = { op: string; key: string; ms: number };
|
||||
|
||||
type Adapter = {
|
||||
timings: Timing[];
|
||||
getObject: (key: string) => Promise<any>;
|
||||
getField: (key: string, field: string) => Promise<any>;
|
||||
getIds: (key: string) => Promise<string[]>;
|
||||
};
|
||||
|
||||
function stringifyObj(o: any) {
|
||||
if (!o) return null;
|
||||
const out: any = {};
|
||||
@ -24,74 +17,104 @@ function stringifyObj(o: any) {
|
||||
return out;
|
||||
}
|
||||
|
||||
function redisAdapter(): Adapter {
|
||||
function getRedisAdapter() {
|
||||
const timings: Timing[] = [];
|
||||
const track = async <T>(op: string, key: string, fn: () => Promise<T>): Promise<T> => {
|
||||
const start = performance.now();
|
||||
const res = await fn();
|
||||
timings.push({ op, key, ms: performance.now() - start });
|
||||
return res;
|
||||
};
|
||||
return {
|
||||
timings,
|
||||
getObject: (key) =>
|
||||
track("hgetall", key, async () => {
|
||||
const o = await redis.hgetall(key);
|
||||
return o && Object.keys(o).length ? o : null;
|
||||
}),
|
||||
getField: (key, field) => track("hget", key, () => redis.hget(key, field)),
|
||||
getIds: (key) => track("smembers", key, async () => (await redis.smembers(key)) || []),
|
||||
async getObject(key: string) {
|
||||
const start = performance.now();
|
||||
const o = await redis.hgetall(key);
|
||||
timings.push({ op: "hgetall", key, ms: performance.now() - start });
|
||||
return o && Object.keys(o).length ? o : null;
|
||||
},
|
||||
async getField(key: string, field: string) {
|
||||
const start = performance.now();
|
||||
const res = await redis.hget(key, field);
|
||||
timings.push({ op: "hget", key, ms: performance.now() - start });
|
||||
return res;
|
||||
},
|
||||
async getIds(key: string) {
|
||||
const start = performance.now();
|
||||
const res = await redis.smembers(key);
|
||||
timings.push({ op: "smembers", key, ms: performance.now() - start });
|
||||
return res || [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function memcachedAdapter(): Adapter {
|
||||
function getMemcachedAdapter() {
|
||||
const timings: Timing[] = [];
|
||||
const getJson = async (key: string) => {
|
||||
|
||||
async function getJson(key: string) {
|
||||
const { value } = await memcached.get(key);
|
||||
return value ? JSON.parse(value.toString()) : null;
|
||||
};
|
||||
const track = async <T>(op: string, key: string, fn: () => Promise<T>): Promise<T> => {
|
||||
const start = performance.now();
|
||||
const res = await fn();
|
||||
timings.push({ op, key, ms: performance.now() - start });
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
timings,
|
||||
getObject: (key) => track("get", key, async () => stringifyObj(await getJson(key))),
|
||||
getField: (key, field) => track("get", key, async () => (await getJson(key))?.[field] ?? null),
|
||||
getIds: (key) => track("get", key, async () => ((await getJson(key)) || []).map(String)),
|
||||
async getObject(key: string) {
|
||||
const start = performance.now();
|
||||
const res = await getJson(key);
|
||||
timings.push({ op: "get", key, ms: performance.now() - start });
|
||||
return stringifyObj(res);
|
||||
},
|
||||
async getField(key: string, field: string) {
|
||||
const start = performance.now();
|
||||
const res = await getJson(key);
|
||||
timings.push({ op: "get", key, ms: performance.now() - start });
|
||||
return res ? res[field] : null;
|
||||
},
|
||||
async getIds(key: string) {
|
||||
const start = performance.now();
|
||||
const res = await getJson(key);
|
||||
timings.push({ op: "get", key, ms: performance.now() - start });
|
||||
return res ? res.map(String) : [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function arangoAdapter(): Adapter {
|
||||
function getArangoAdapter() {
|
||||
const timings: Timing[] = [];
|
||||
const getVal = async (key: string) => {
|
||||
|
||||
async function getVal(key: string) {
|
||||
const doc = await arangoKv.document(key, { graceful: true });
|
||||
return doc ? doc.value : null;
|
||||
};
|
||||
const track = async <T>(op: string, key: string, fn: () => Promise<T>): Promise<T> => {
|
||||
const start = performance.now();
|
||||
const res = await fn();
|
||||
timings.push({ op, key, ms: performance.now() - start });
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
timings,
|
||||
getObject: (key) => track("document", key, async () => stringifyObj(await getVal(key))),
|
||||
getField: (key, field) => track("document", key, async () => (await getVal(key))?.[field] ?? null),
|
||||
getIds: (key) => track("document", key, async () => ((await getVal(key)) || []).map(String)),
|
||||
async getObject(key: string) {
|
||||
const start = performance.now();
|
||||
const res = await getVal(key);
|
||||
timings.push({ op: "document", key, ms: performance.now() - start });
|
||||
return stringifyObj(res);
|
||||
},
|
||||
async getField(key: string, field: string) {
|
||||
const start = performance.now();
|
||||
const res = await getVal(key);
|
||||
timings.push({ op: "document", key, ms: performance.now() - start });
|
||||
return res ? res[field] : null;
|
||||
},
|
||||
async getIds(key: string) {
|
||||
const start = performance.now();
|
||||
const res = await getVal(key);
|
||||
timings.push({ op: "document", key, ms: performance.now() - start });
|
||||
return res ? res.map(String) : [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getAdapter(db: string): Adapter {
|
||||
if (db === "memcached") return memcachedAdapter();
|
||||
if (db === "arangodb") return arangoAdapter();
|
||||
return redisAdapter();
|
||||
function getAdapter(db: string) {
|
||||
if (db === "memcached") return getMemcachedAdapter();
|
||||
if (db === "arangodb") return getArangoAdapter();
|
||||
return getRedisAdapter();
|
||||
}
|
||||
|
||||
function timingSummary(timings: Timing[]) {
|
||||
const total = timings.reduce((s, t) => s + t.ms, 0);
|
||||
let total = 0;
|
||||
for (const t of timings) {
|
||||
total += t.ms;
|
||||
}
|
||||
return { count: timings.length, total, ops: timings };
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user