Packages
game_server_sdk
1.0.1022
1.0.1082
1.0.1079
1.0.1078
1.0.1077
1.0.1076
1.0.1075
1.0.1074
1.0.1073
1.0.1070
1.0.1068
1.0.1067
1.0.1063
1.0.1059
1.0.1058
1.0.1057
1.0.1056
1.0.1055
1.0.1050
1.0.1049
1.0.1048
1.0.1047
1.0.1046
1.0.1044
1.0.1043
1.0.1042
1.0.1041
1.0.1040
1.0.1039
1.0.1038
1.0.1034
1.0.1033
1.0.1029
1.0.1028
1.0.1026
1.0.1025
1.0.1024
1.0.1023
1.0.1022
1.0.1021
1.0.1020
1.0.1019
1.0.1018
1.0.1017
1.0.1016
1.0.1015
1.0.1014
1.0.1013
1.0.1012
1.0.1011
1.0.1009
1.0.1008
1.0.1007
1.0.1006
1.0.1005
1.0.1004
1.0.1003
1.0.1001
1.0.999
1.0.998
1.0.997
1.0.996
1.0.995
1.0.994
1.0.993
1.0.992
1.0.991
1.0.990
1.0.989
1.0.988
1.0.987
1.0.986
1.0.985
1.0.984
1.0.983
1.0.982
1.0.981
1.0.980
1.0.979
1.0.978
1.0.977
1.0.976
1.0.975
1.0.974
1.0.973
1.0.972
1.0.971
1.0.970
1.0.969
1.0.968
1.0.967
1.0.966
1.0.965
1.0.964
1.0.963
1.0.962
1.0.961
1.0.959
1.0.958
1.0.956
1.0.951
1.0.950
1.0.943
1.0.942
1.0.941
1.0.940
1.0.938
1.0.936
1.0.935
1.0.931
1.0.929
1.0.928
1.0.927
1.0.926
1.0.925
1.0.924
1.0.923
1.0.921
1.0.920
1.0.919
1.0.918
1.0.917
1.0.916
1.0.911
1.0.910
1.0.902
1.0.899
1.0.898
1.0.897
1.0.896
1.0.894
1.0.893
1.0.891
1.0.890
1.0.889
1.0.888
1.0.887
1.0.886
1.0.885
1.0.884
1.0.883
1.0.882
1.0.881
1.0.880
1.0.879
1.0.878
1.0.877
1.0.26
1.0.25
1.0.22
1.0.21
1.0.20
1.0.19
1.0.15
1.0.14
1.0.13
1.0.12
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.1.0
SDK for GameServer hooks development. Provides type specs, documentation, and IDE autocomplete for GameServer modules without requiring the full server.
Current section
Files
Jump to
Current section
Files
lib/game_server/cache.ex
defmodule GameServer.Cache do
@moduledoc ~S"""
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
end
Equivalent to:
case GameServer.Cache.get(key) do
nil ->
result = fun.()
GameServer.Cache.put(key, result, opts)
result
cached ->
cached
end
## Manual 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
end
## Cache 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
end
**Note:** This is an SDK stub. The actual implementation uses Nebulex on
the GameServer.
"""
@doc """
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 cached(term(), keyword(), (-> term())) :: term()
def cached(_key, _opts \\ [], _fun) do
stub!("cached/3")
end
@doc "Get a cached value by key. Returns `nil` on cache miss."
@spec get(term()) :: term() | nil
def get(_key) do
stub!("get/1")
end
@doc """
Store a value in the cache.
## Options
- `:ttl` — time-to-live in milliseconds (e.g. `ttl: :timer.minutes(10)`)
"""
@spec put(term(), term(), keyword()) :: term()
def put(_key, _value, _opts \\ []) do
stub!("put/3")
end
@doc "Delete a cache entry by key."
@spec delete(term()) :: :ok
def delete(_key) do
stub!("delete/1")
end
@doc "Check whether a key exists in the cache."
@spec has_key?(term()) :: boolean()
def has_key?(_key) do
stub!("has_key?/1")
end
@doc """
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`)
"""
@spec incr(term(), integer(), keyword()) :: integer()
def incr(_key, _amount \\ 1, _opts \\ []) do
stub!("incr/3")
end
defp stub!(fun) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder -> nil
_ -> raise "GameServer.Cache.#{fun} is a stub - only available at runtime on GameServer"
end
end
end