asobi_quests_cache (asobi_quests v0.2.2)

View Source

The active definitions, in ETS, so progress/3 does not query for them.

game.quests.progress(player, "kills", 1) runs on a gameplay event. Reading the definition table on every kill would put a query on the hottest path an extension has, to fetch rows that change when an operator edits a quest and otherwise never.

This is also where the library-application shape bites. With no mod in the .app.src there is no start/2, so the ETS table is created in this process's init/1 and every reader has to cope with there being no loaded set

  • before init/1 has run at all, between it and the first load finishing, and after this extension has burned its restart budget and gone dark. Readers fall back to the database rather than crashing the caller.

A load failure does not crash either. Under asobi_extension_child_sup a crash loop ends with the whole extension dark and staying dark, so a database that is briefly unreachable at boot must not be fatal: the load logs, keeps the last good contents, and retries.

Summary

Functions

One definition by key, active or not.

Active definitions listening for Counter.

Reload on the next message. Called after any definition write.

Whether the cache holds a complete set.

Types

state()

-type state() :: #{timer := reference() | undefined}.

Functions

by_key(QuestKey)

-spec by_key(binary()) -> {ok, asobi_quests:quest()} | {error, not_found}.

One definition by key, active or not.

for_counter(Counter)

-spec for_counter(binary()) -> {ok, [asobi_quests:quest()]} | {error, term()}.

Active definitions listening for Counter.

handle_call(Request, From, State)

-spec handle_call(term(), gen_server:from(), state()) -> {reply, ok, state()}.

handle_cast/2

-spec handle_cast(reload, state()) -> {noreply, state()}.

handle_continue/2

-spec handle_continue(load, state()) -> {noreply, state()}.

handle_info/2

-spec handle_info(reload | term(), state()) -> {noreply, state()}.

init/1

-spec init([]) -> {ok, state(), {continue, load}}.

invalidate()

-spec invalidate() -> ok.

Reload on the next message. Called after any definition write.

loaded()

-spec loaded() -> boolean().

Whether the cache holds a complete set.

False when the extension is not supervised at all, false between init/1 creating the table and the first load finishing, and false during a reload. Every one of those is a state in which a reader must go to the database.

start_link()

-spec start_link() -> gen_server:start_ret().

terminate/2

-spec terminate(term(), state()) -> ok.