from test/more import *;
requires_capability("db");
requires_capability("proc");
from std/cache/lru import Cache;
from std/db import DB;
from std/proc import sleep_async;
from std/task import all;
let dbh := DB.temp();
dbh.prepare( "create table kv (k text, v text)" ).execute();
dbh.prepare( "insert into kv (k, v) values ('a', 'alpha')" ).execute();
dbh.prepare( "insert into kv (k, v) values ('b', 'beta')" ).execute();
let lookups := 0;
let cache := new Cache( capacity: 8 );
function db_lookup ( key ) {
lookups++;
let q := dbh.prepare( "select v from kv where k = ?" );
q.execute(key);
let row := q.next_array();
return row[0];
}
async function fetch_cached ( key ) {
await {
sleep_async(0.01);
};
return cache.get( key, db_lookup );
}
let values := await {
all(
[
fetch_cached("a"),
fetch_cached("a"),
fetch_cached("b"),
fetch_cached("a"),
],
);
};
is( values[0], "alpha", "first cached lookup resolves from db" );
is( values[2], "beta", "second key resolves from db" );
is( lookups, 2, "cache wraps db lookups under concurrent async calls" );
done_testing();