View Source Nostrum.Cache.ChannelCache behaviour (Nostrum v0.8.0)
Cache behaviour & dispatcher for direct message channels.
You can call the functions provided by this module independent of which cache is configured, and it will dispatch to the configured cache implementation. The user-facing functions for reading the cache can be found in the "Reading the cache" section.
By default, Elixir.Nostrum.Cache.ChannelCache.ETS will be used for caching channels.
You can override this in the :caches
option of the :nostrum
application
by setting the :channels
field to a different module implementing the
Nostrum.Cache.ChannelCache
behaviour. Any module below
Nostrum.Cache.ChannelCache
can be used as a cache.
writing-your-own-channel-cache
Writing your own channel cache
As with the other caches, the channel cache API consists of three parts:
Functions called by nostrum, such as
create/1
orupdate/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 byNostrum.Api
instead.the QLC query handle for read operations,
query_handle/0
, andthe
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 channel 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
Callbacks
Retrieve the child specification for starting this mapping under a supervisor.
Create a channel in the cache.
Delete a channel from the cache.
Return a QLC query handle for cache read operations.
Update a channel from upstream data.
A function that should wrap any :qlc
operations.
Functions
Look up a channel in the cache, by message or ID.
Same as get/1
, but raises Nostrum.Error.CacheError
in case of failure.
Return the QLC handle of the configured cache.
Link to this section Types
@type reason() :: :not_found
Specifies the reason for why a lookup operation has failed.
Link to this section Callbacks
@callback child_spec(term()) :: Supervisor.child_spec()
Retrieve the child specification for starting this mapping under a supervisor.
@callback create(map()) :: Nostrum.Struct.Channel.t()
Create a channel in the cache.
@callback delete(Nostrum.Struct.Channel.id()) :: :noop | Nostrum.Struct.Channel.t()
Delete a channel from the cache.
Return the old channel if it was cached, or nil
otherwise.
@callback query_handle() :: :qlc.query_handle()
Return a QLC query handle for cache read operations.
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 {channel_id, channel}
, where:
channel_id
is aNostrum.Struct.Channel.id/0
, andchannel
is aNostrum.Struct.Channel.t/0
If your cache needs some form of setup or teardown for QLC queries (such as
opening connections), see wrap_qlc/1
.
@callback update(Nostrum.Struct.Channel.t()) :: {Nostrum.Struct.Channel.t() | nil, Nostrum.Struct.Channel.t()}
Update a channel from upstream data.
Return the original channel before the update, and the updated channel.
@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
@spec get(Nostrum.Struct.Channel.id() | Nostrum.Struct.Message.t()) :: {:ok, Nostrum.Struct.Channel.t()} | {:error, reason()}
Look up a channel in the cache, by message or ID.
An optional second argument can be passed to select the cache to read from.
@spec get(Nostrum.Struct.Channel.id() | Nostrum.Struct.Message.t(), module()) :: {:ok, Nostrum.Struct.Channel.t()} | {:error, reason()}
@spec get!(Nostrum.Struct.Channel.id() | Nostrum.Struct.Message.t()) :: no_return() | Nostrum.Struct.Channel.t()
Same as get/1
, but raises Nostrum.Error.CacheError
in case of failure.
@spec get!(Nostrum.Struct.Channel.id() | Nostrum.Struct.Message.t(), module()) :: no_return() | Nostrum.Struct.Channel.t()
Return the QLC handle of the configured cache.