wasm_file_cache (wasm v0.3.0)
View SourceA directory of files, bounded by total size, oldest first.
The policy behind both on-disk caches this runtime keeps: generated code in
wasm_code_cache and snapshot images in wasm_snapshot_store. It was written
once for the first and copied nowhere, which left the second growing without
bound; it lives here now so there is one copy and one set of cases.
Plain module code, called from whichever process is storing. No server, no lock, no timer. Eviction happens on a store and nowhere else: a directory only grows when something is written to it, so that is the only moment it can need shrinking. A node that stores nothing never evicts, and a directory already over its cap stays over it until the next store.
What "oldest" means
Least recently used, not least recently written, because a reader calls
touch/1 on a hit. That is the only thing separating the two, and it is worth
knowing that without it eviction still looks correct: it stays under the cap,
it just throws away the entries being used.
What it does when something goes wrong
Nothing raises and nothing is reported. An unreadable directory answers no
entries and so evicts nothing. A failed delete is ignored, and drop/3
subtracts the size it expected to free either way, so a file that will not go
cannot make the loop spin. Two processes evicting at once both enumerate, both
delete, and the second delete fails with enoent: the result is over-eviction
rather than corruption, and over-eviction costs a recompile or a recapture.
Summary
Functions
Every entry, oldest not first. [] for a directory that cannot be read.
Remove every entry and every temporary. For tests, and for a clean start.
Sweep stale temporaries, then drop oldest entries until the total fits.
Note that an entry was used, so eviction can tell which ones are.
Functions
-spec entries(file:filename(), string()) -> [file:filename()].
Every entry, oldest not first. [] for a directory that cannot be read.
-spec purge(file:filename(), string()) -> ok.
Remove every entry and every temporary. For tests, and for a clean start.
-spec sweep_and_evict(file:filename(), string(), non_neg_integer(), file:filename() | undefined) -> ok.
Sweep stale temporaries, then drop oldest entries until the total fits.
Suffix selects the entries, ".img" or ".beam". Temporaries are always
*.tmp, are swept by age, and are counted as neither entries nor bytes.
Keep is a path that must not be dropped whatever its age, which a caller
passes for the entry it has just written. Without it a store larger than the
whole cap writes a file and immediately deletes it, and the caller is left
believing it filed something.
-spec touch(file:filename()) -> ok.
Note that an entry was used, so eviction can tell which ones are.
The result is dropped: a read-only directory degrades to least-recently-written rather than failing a lookup that otherwise worked.