Skip to content

Commit

Permalink
remove QLC from User and Presence caches
Browse files Browse the repository at this point in the history
  • Loading branch information
Th3-M4jor committed Aug 20, 2024
1 parent c5a2989 commit d2f746b
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 109 deletions.
47 changes: 9 additions & 38 deletions lib/nostrum/cache/presence_cache.ex
Original file line number Diff line number Diff line change
Expand Up @@ -92,42 +92,19 @@ defmodule Nostrum.Cache.PresenceCache do
"""
@callback child_spec(term()) :: Supervisor.child_spec()

@doc """
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](https://www.erlang.org/doc/man/qlc.html#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, user_id}, presence}`, where:
- `guild_id` is a `t:Nostrum.Struct.Guild.id/0`, and
- `user_id` is a `t:Nostrum.Struct.User.id/0`, and
- `presence` is a `t:presence/0`.
If your cache needs some form of setup or teardown for QLC queries (such as
opening connections), see `c:wrap_qlc/1`.
"""
@doc since: "0.8.0"
@callback query_handle() :: :qlc.query_handle()

@doc """
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)`.
will then effectively call `wrap_query(fn -> ... end)`.
If your cache does not need any wrapping, you can omit this.
"""
@doc since: "0.8.0"
@callback wrap_qlc((-> result)) :: result when result: term()
@optional_callbacks wrap_qlc: 1
@callback wrap_query((-> result)) :: result when result: term()
@optional_callbacks wrap_query: 1

# Dispatch
@doc false
Expand All @@ -151,24 +128,18 @@ defmodule Nostrum.Cache.PresenceCache do
end

@doc """
Call `c:wrap_qlc/1` on the given cache, if implemented.
Call `c:wrap_query/1` on the given cache, if implemented.
If no cache is given, calls out to the default cache.
"""
@doc since: "0.8.0"
@spec wrap_qlc((-> result)) :: result when result: term()
@spec wrap_qlc(module(), (-> result)) :: result when result: term()
def wrap_qlc(cache \\ @configured_cache, fun) do
if function_exported?(cache, :wrap_qlc, 1) do
cache.wrap_qlc(fun)
@spec wrap_query((-> result)) :: result when result: term()
@spec wrap_query(module(), (-> result)) :: result when result: term()
def wrap_query(cache \\ @configured_cache, fun) do
if function_exported?(cache, :wrap_query, 1) do
cache.wrap_query(fun)
else
fun.()
end
end

@doc """
Return the QLC handle of the configured cache.
"""
@doc since: "0.8.0"
defdelegate query_handle(), to: @configured_cache
end
6 changes: 0 additions & 6 deletions lib/nostrum/cache/presence_cache/ets.ex
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,4 @@ defmodule Nostrum.Cache.PresenceCache.ETS do
:ets.insert(@table_name, {{guild_id, p.user.id}, p})
end)
end

@impl PresenceCache
@doc "Retrieve a query handle for QLC queries."
@doc since: "0.8.0"
@spec query_handle :: :qlc.query_handle()
def query_handle, do: :ets.table(@table_name)
end
14 changes: 2 additions & 12 deletions lib/nostrum/cache/presence_cache/mnesia.ex
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,9 @@ if Code.ensure_loaded?(:mnesia) do
end

@impl PresenceCache
@doc "Retrieve a query handle for the table."
@doc "Wrap query operations in a transaction."
@doc since: "0.8.0"
@spec query_handle :: :qlc.query_handle()
def query_handle do
# Note: :"$1" holds a pair here (`{guild_id, user_id}`).
ms = [{{:_, :"$1", :"$2"}, [], [{{:"$1", :"$2"}}]}]
:mnesia.table(@table_name, {:traverse, {:select, ms}})
end

@impl PresenceCache
@doc "Wrap QLC operations in a transaction."
@doc since: "0.8.0"
def wrap_qlc(fun) do
def wrap_query(fun) do
:mnesia.activity(:sync_transaction, fun)
end
end
Expand Down
3 changes: 0 additions & 3 deletions lib/nostrum/cache/presence_cache/noop.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,4 @@ defmodule Nostrum.Cache.PresenceCache.NoOp do
@impl PresenceCache
@spec bulk_create(Guild.id(), [map]) :: :ok
def bulk_create(_guild_id, _presences), do: :ok

@impl PresenceCache
def query_handle, do: :qlc.string_to_handle(~c"[].")
end
40 changes: 9 additions & 31 deletions lib/nostrum/cache/user_cache.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,36 +57,19 @@ defmodule Nostrum.Cache.UserCache do
"""
@callback delete(snowflake :: User.id()) :: :noop | User.t()

@doc """
Return a query handle for usage with `:qlc`.
This is used by nostrum to provide automatic joins between the member and the
user cache, and may be used for other functions in the future.
The Erlang manual on [Implementing a QLC
Table](https://www.erlang.org/doc/man/qlc.html#implementing_a_qlc_table)
contains examples for implementation.
The query handle must return items in the form `{user_id, user}`, where
`user_id` is a `t:Nostrum.Struct.User.id/0` and `user` is a
`t:Nostrum.Struct.User.t/0`.
"""
@doc since: "0.7.0"
@callback query_handle() :: :qlc.query_handle()

@doc """
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)`.
will then effectively call `wrap_query(fn -> ... end)`.
If your cache does not need any wrapping, you can omit this.
"""
@doc since: "0.8.0"
@callback wrap_qlc((-> result)) :: result when result: term()
@optional_callbacks wrap_qlc: 1
@callback wrap_query((-> result)) :: result when result: term()
@optional_callbacks wrap_query: 1

@doc """
Retrieve the child specification for starting this mapping under a supervisor.
Expand Down Expand Up @@ -116,22 +99,17 @@ defmodule Nostrum.Cache.UserCache do
@spec get!(User.id()) :: no_return | User.t()
def get!(id) when is_snowflake(id), do: id |> get() |> Util.bangify_find(id, __MODULE__)

@doc "Call `c:query_handle/0` on the configured cache."
@doc since: "0.8.0"
@spec query_handle() :: :qlc.query_handle()
defdelegate query_handle, to: @configured_cache

@doc """
Call `c:wrap_qlc/1` on the given cache, if implemented.
Call `c:wrap_query/1` on the given cache, if implemented.
If no cache is given, calls out to the default cache.
"""
@doc since: "0.8.0"
@spec wrap_qlc((-> result)) :: result when result: term()
@spec wrap_qlc(module(), (-> result)) :: result when result: term()
def wrap_qlc(cache \\ @configured_cache, fun) do
if function_exported?(cache, :wrap_qlc, 1) do
cache.wrap_qlc(fun)
@spec wrap_query((-> result)) :: result when result: term()
@spec wrap_query(module(), (-> result)) :: result when result: term()
def wrap_query(cache \\ @configured_cache, fun) do
if function_exported?(cache, :wrap_query, 1) do
cache.wrap_query(fun)
else
fun.()
end
Expand Down
8 changes: 0 additions & 8 deletions lib/nostrum/cache/user_cache/ets.ex
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,4 @@ defmodule Nostrum.Cache.UserCache.ETS do
:noop
end
end

@doc "Get a QLC query handle for the user cache."
@doc since: "0.7.0"
@impl Nostrum.Cache.UserCache
@spec query_handle :: :qlc.query_handle()
def query_handle do
:ets.table(@table_name)
end
end
9 changes: 1 addition & 8 deletions lib/nostrum/cache/user_cache/mnesia.ex
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,9 @@ if Code.ensure_loaded?(:mnesia) do
end)
end

@impl UserCache
@doc "Get a QLC query handle for the user cache."
@spec query_handle :: :qlc.query_handle()
def query_handle do
:mnesia.table(@table_name)
end

@impl UserCache
@doc "Wrap QLC operations in a transaction."
def wrap_qlc(fun) do
def wrap_query(fun) do
:mnesia.activity(:sync_transaction, fun)
end
end
Expand Down
3 changes: 0 additions & 3 deletions lib/nostrum/cache/user_cache/noop.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,4 @@ defmodule Nostrum.Cache.UserCache.NoOp do

@impl Nostrum.Cache.UserCache
def delete(_id), do: :noop

@impl Nostrum.Cache.UserCache
def query_handle, do: :qlc.string_to_handle(~c"[].")
end

0 comments on commit d2f746b

Please sign in to comment.