View Source Nostrum.Cache.GuildCache behaviour (Nostrum v0.8.0)

Cache behaviour & dispatcher for guilds.

You can call the functions provided by this module independent of which cache is configured, and it will dispatch to the configured cache implementation.

By default, Elixir.Nostrum.Cache.GuildCache.ETS will be used for caching guilds. You can override this in the :caches option of the :nostrum application by setting the :guilds field to a different module implementing the Nostrum.Cache.GuildCache behaviour. Any module below Nostrum.Cache.GuildCache can be used as a cache.

writing-your-own-guild-cache

Writing your own guild cache

As with the other caches, the guild cache API consists of two parts:

  • The functions that nostrum calls, such as create/1 or update/1. These do not create any objects in the Discord API, they are purely created to update the cached data from data that Discord sends us. If you want to create objects on Discord, use the functions exposed by Nostrum.Api instead.

  • the QLC query handle for read operations, query_handle/0, and

  • the child_spec/1 callback for starting the cache under a supervisor.

You need to implement all of them for nostrum to work with your custom cache.

The "upstream data" wording in this module references the fact that the data that the guild cache (and other caches) retrieves represents the raw data we receive from the upstream connection, no attempt is made by nostrum to sanitize the data before it enters the cache. Caching implementations need to cast the data to the resulting type themselves. A possible future improvement would be moving the data casting into this module before the backing cache implementation is called.

Link to this section Summary

Types

A selector for looking up entries in the cache.

Callbacks

Create a channel for the guild from upstream data.

Delete the given channel from the guild.

Update the given channel on the given guild from upstream data.

Retrieve the child specification for starting this mapping under a supervisor.

Create a guild in the cache.

Delete a guild from the cache.

Update the emoji list of the given guild from upstream data.

Decrement the member count for this guild by one.

Increment the member count for this guild by one.

Return a QLC query handle for cache read operations.

Create a role on the given guild from upstream data.

Delete the given role on the given guild.

Update a role on the given guild from upstream data.

Update a guild from upstream data.

Update the voice state of the given guild from upstream data.

A function that should wrap any :qlc operations.

Functions

Retrieves all Nostrum.Struct.Guild from the cache.

Fold (reduce) over all guilds in the cache.

Retrieves a single Nostrum.Struct.Guild from the cache via its id.

Same as get/1, but raises Nostrum.Error.CacheError in case of failure.

Return the QLC handle of the configured cache.

Selects values using a selector from a Nostrum.Struct.Guild.

Same as select/2, but raises Nostrum.Error.CacheError in case of failure.

Selects guilds matching selector from all Nostrum.Struct.Guild in the cache.

Call wrap_qlc/1 on the given cache, if implemented.

Link to this section Types

@type selector() :: (Nostrum.Struct.Guild.t() -> any())

A selector for looking up entries in the cache.

Link to this section Callbacks

Link to this callback

channel_create(id, channel)

View Source
@callback channel_create(Nostrum.Struct.Guild.id(), channel :: map()) ::
  Nostrum.Struct.Channel.t()

Create a channel for the guild from upstream data.

Return the adapted Nostrum.Struct.Channel.t/0 structure.

@callback channel_delete(Nostrum.Struct.Guild.id(), Nostrum.Struct.Channel.id()) ::
  Nostrum.Struct.Channel.t() | :noop

Delete the given channel from the guild.

If the channel was cached, return the original channel. Return :noop otherwise.

Link to this callback

channel_update(id, channel)

View Source
@callback channel_update(Nostrum.Struct.Guild.id(), channel :: map()) ::
  {old_channel :: Nostrum.Struct.Channel.t() | nil,
   new_channel :: Nostrum.Struct.Channel.t()}

Update the given channel on the given guild from upstream data.

Return the original channel before the update if known, and the updated channel.

@callback child_spec(term()) :: Supervisor.child_spec()

Retrieve the child specification for starting this mapping under a supervisor.

@callback create(map()) :: Nostrum.Struct.Guild.t()

Create a guild in the cache.

@callback delete(Nostrum.Struct.Guild.id()) :: Nostrum.Struct.Guild.t() | nil

Delete a guild from the cache.

Return the old guild if it was cached, or nil otherwise.

Link to this callback

emoji_update(id, emojis)

View Source
@callback emoji_update(Nostrum.Struct.Guild.id(), emojis :: [map()]) ::
  {old_emojis :: [Nostrum.Struct.Emoji.t()],
   new_emojis :: [Nostrum.Struct.Emoji.t()]}

Update the emoji list of the given guild from upstream data.

Discord sends us the complete emoji list on an update, which is passed here.

Return the old list of emojis before the update, and the updated list of emojis.

Link to this callback

member_count_down(id)

View Source (since 0.7.0)
@callback member_count_down(Nostrum.Struct.Guild.id()) :: true

Decrement the member count for this guild by one.

Link to this callback

member_count_up(id)

View Source (since 0.7.0)
@callback member_count_up(Nostrum.Struct.Guild.id()) :: true

Increment the member count for this guild by one.

Link to this callback

query_handle()

View Source (since 0.8.0)
@callback query_handle() :: :qlc.query_handle()

Return a QLC query handle for cache read operations.

This is used by nostrum to provide any read operations on the cache. Write operations still need to be implemented separately.

The Erlang manual on Implementing a QLC Table contains examples for implementation. To prevent full table scans, accept match specifications in your TraverseFun and implement a LookupFun as documented.

The query handle must return items in the form {guild_id, guild}, where:

If your cache needs some form of setup or teardown for QLC queries (such as opening connections), see wrap_qlc/1.

@callback role_create(Nostrum.Struct.Guild.id(), role :: map()) ::
  {Nostrum.Struct.Guild.id(), new_role :: Nostrum.Struct.Guild.Role.t()}

Create a role on the given guild from upstream data.

Return the casted role.

Delete the given role on the given guild.

Return the guild and the old role if it was cached, or :noop otherwise.

@callback role_update(Nostrum.Struct.Guild.id(), role :: map()) ::
  {Nostrum.Struct.Guild.id(), old_role :: Nostrum.Struct.Guild.Role.t() | nil,
   new_role :: Nostrum.Struct.Guild.Role.t()}

Update a role on the given guild from upstream data.

Return the old role before the update and the updated role.

@callback update(map()) ::
  {old_guild :: Nostrum.Struct.Guild.t() | nil,
   updated_guild :: Nostrum.Struct.Guild.t()}

Update a guild from upstream data.

Return the original guild before the update (if it was cached) and the updated guild.

Link to this callback

voice_state_update(id, state)

View Source
@callback voice_state_update(Nostrum.Struct.Guild.id(), state :: map()) ::
  {Nostrum.Struct.Guild.id(), new_state :: [map()]}

Update the voice state of the given guild from upstream data.

Note that it is recommended to drop the :member / "member" keys of the supplied upstream data, as these would otherwise duplicate the data that is being kept in the guild cache already.

Return the guild ID and the updated voice states of the guild.

Link to this callback

wrap_qlc(function)

View Source (optional) (since 0.8.0)
@callback wrap_qlc((() -> result)) :: result when result: term()

A function that should wrap any :qlc operations.

If you implement a cache that is backed by a database and want to perform cleanup and teardown actions such as opening and closing connections, managing transactions and so on, you want to implement this function. nostrum will then effectively call wrap_qlc(fn -> :qlc.e(...) end).

If your cache does not need any wrapping, you can omit this.

Link to this section Functions

Link to this function

all(cache \\ Nostrum.Cache.GuildCache.ETS)

View Source
This function is deprecated. Use fold/2-3 instead.

Retrieves all Nostrum.Struct.Guild from the cache.

Link to this function

fold(acc, reducer, cache \\ Nostrum.Cache.GuildCache.ETS)

View Source (since 0.8.0)
@spec fold(acc, (Nostrum.Struct.Guild.t(), acc -> acc), module()) :: acc
when acc: term()

Fold (reduce) over all guilds in the cache.

parameters

Parameters

  • acc: The initial accumulator. Also returned if no guilds are cached.
  • fun: Called for every guild in the result. Takes a pair in the form {guild, acc}, and must return the updated accumulator.
  • cache (optional): The cache to use. nostrum will use the cache configured at compile time by default.
Link to this function

get(guild_id, cache \\ Nostrum.Cache.GuildCache.ETS)

View Source
@spec get(Nostrum.Struct.Guild.id(), module()) ::
  {:ok, Nostrum.Struct.Guild.t()} | {:error, :not_found}

Retrieves a single Nostrum.Struct.Guild from the cache via its id.

Returns {:error, :not_found} if no result was found.

Same as get/1, but raises Nostrum.Error.CacheError in case of failure.

Link to this function

query_handle()

View Source (since 0.8.0)

Return the QLC handle of the configured cache.

Link to this function

select(guild_id, selector)

View Source
This function is deprecated. Use `with {:ok, result} = GuildCache.get(guild_id), my_result = selector(result)` instead.
@spec select(Nostrum.Struct.Guild.id(), selector()) ::
  {:ok, any()} | {:error, :not_found}

Selects values using a selector from a Nostrum.Struct.Guild.

Returns {:error, reason} if no result was found.

Link to this function

select!(guild_id, selector)

View Source
@spec select!(Nostrum.Struct.Guild.id(), selector()) :: any() | no_return()

Same as select/2, but raises Nostrum.Error.CacheError in case of failure.

This function is deprecated. Use fold/2-3 instead.
@spec select_all(selector :: (Nostrum.Struct.Guild.t() -> any())) :: Enum.t()

Selects guilds matching selector from all Nostrum.Struct.Guild in the cache.

Link to this function

wrap_qlc(cache \\ Nostrum.Cache.GuildCache.ETS, fun)

View Source (since 0.8.0)
@spec wrap_qlc(module(), (() -> result)) :: result when result: term()

Call wrap_qlc/1 on the given cache, if implemented.

If no cache is given, calls out to the default cache.