In-memory cache backed by Nebulex (2-level near-cache topology).
Plugins can use this to cache expensive computations (e.g. API calls, PDF generation, data transformations) so that repeated hook calls return instantly from cache.
Quick start — cached/3
The simplest way to cache a hook function. Checks the cache first; on miss, runs the function, stores the result, and returns it:
defmodule GameServer.Modules.MyPlugin do
use GameServer.Hooks
def generate_cheatsheet(lang) do
GameServer.Cache.cached({:my_plugin, :cheatsheet, lang}, ttl: :timer.minutes(30), fn ->
do_expensive_pdf_generation(lang)
end)
end
endEquivalent to:
case GameServer.Cache.get(key) do
nil ->
result = fun.()
GameServer.Cache.put(key, result, opts)
result
cached ->
cached
endManual get/put
For more control (conditional caching, partial updates, etc.):
def my_hook(lang) do
cache_key = {:my_plugin, :data, lang}
case GameServer.Cache.get(cache_key) do
nil ->
result = expensive_work(lang)
GameServer.Cache.put(cache_key, result, ttl: :timer.minutes(10))
{:ok, result}
cached ->
{:ok, cached}
end
endCache keys
Use namespaced tuples to avoid collisions with other plugins and the server:
{:my_plugin, :resource_type, resource_id}Options
:ttl— time-to-live in milliseconds. After this time the entry is automatically evicted. If omitted, the entry lives until explicitly deleted or the cache is full (LRU eviction).
Version-based invalidation
For data that changes (e.g. leaderboard entries, user profiles), embed a version counter in the cache key. When data changes, increment the version so the next read produces a cache miss:
defp my_version(entity_id) do
GameServer.Cache.get({:my_plugin, :version, entity_id}) || 1
end
defp invalidate(entity_id) do
GameServer.Cache.incr({:my_plugin, :version, entity_id}, 1, default: 1)
end
def get_data(entity_id) do
vsn = my_version(entity_id)
cache_key = {:my_plugin, :data, vsn, entity_id}
case GameServer.Cache.get(cache_key) do
nil ->
data = fetch_from_db(entity_id)
GameServer.Cache.put(cache_key, data, ttl: :timer.minutes(5))
{:ok, data}
cached ->
{:ok, cached}
end
endNote: This is an SDK stub. The actual implementation uses Nebulex on the GameServer.
Summary
Functions
Cache-through helper: returns the cached value for key, or computes and
caches the result of fun.
Delete a cache entry by key.
Get a cached value by key. Returns nil on cache miss.
Check whether a key exists in the cache.
Atomically increment a numeric counter.
Store a value in the cache.
Functions
Cache-through helper: returns the cached value for key, or computes and
caches the result of fun.
This is the recommended way to add caching to hook functions. It combines
get + put in a single call:
GameServer.Cache.cached({:my_plugin, :data, id}, ttl: :timer.minutes(10), fn ->
expensive_computation(id)
end)Options
:ttl— time-to-live in milliseconds
@spec delete(term()) :: :ok
Delete a cache entry by key.
Get a cached value by key. Returns nil on cache miss.
Check whether a key exists in the cache.
Atomically increment a numeric counter.
Returns the new value. Creates the counter with the :default value if it
doesn't exist.
Options
:default— initial value if key doesn't exist (default:0)
Store a value in the cache.
Options
:ttl— time-to-live in milliseconds (e.g.ttl: :timer.minutes(10))