### Configure cache to use custom serializer Source: https://hexdocs.pm/nebulex_redis_adapter Configure your cache to use the custom serializer defined in the previous example. ```elixir config :my_app, MyApp.RedisCache, serializer: MyApp.JSONSerializer ``` -------------------------------- ### Query API examples with get_all! and stream! Source: https://hexdocs.pm/nebulex_redis_adapter Shows the query API for pattern matching and key selection. The `KEYS` command is used, which can block Redis and cause performance issues in production; prefer explicit key lists or `stream/2` for large datasets. ```elixir iex> MyApp.RedisCache.put_all(%{ ...> "firstname" => "Albert", ...> "lastname" => "Einstein", ...> "age" => 76 ...> }) :ok # returns key/value pairs by default iex> MyApp.RedisCache.get_all!("*name*") |> Map.new() %{"firstname" => "Albert", "lastname" => "Einstein"} iex> MyApp.RedisCache.get_all!("*name*", select: :key) ["firstname", "lastname"] iex> MyApp.RedisCache.get_all!("a??", select: :key) ["age"] iex> MyApp.RedisCache.get_all!(select: :key) ["age", "firstname", "lastname"] iex> MyApp.RedisCache.stream!("*name*", select: :key) |> Enum.to_list() ["firstname", "lastname"] ``` -------------------------------- ### Using fetch_conn(key: "mylist") with Redix.pipeline!() Source: https://hexdocs.pm/nebulex_redis_adapter Shows how to use fetch_conn/1 with the :key option, which is required for :redis_cluster and :client_side_cluster modes. The example uses Redix.pipeline! to run multiple commands on the same connection, ensuring they target the same Redis instance. ```elixir iex> {:ok, conn} = MyCache.fetch_conn(key: "mylist") iex> Redix.pipeline!(conn, [ ...> ["LPUSH", "mylist", "hello"], ...> ["LPUSH", "mylist", "world"], ...> ["LRANGE", "mylist", "0", "-1"] ...> ]) [1, 2, ["world", "hello"]] ``` -------------------------------- ### Encoding and decoding Elixir terms with encode_key/encode_value/decode_value Source: https://hexdocs.pm/nebulex_redis_adapter Shows how to encode Elixir terms into Redis keys and values, and decode them back. The example uses encode_key/2, encode_value/2, and decode_value/2 with a custom timeout of 5000 ms. ```elixir iex> conn = MyCache.fetch_conn!() iex> key = MyCache.encode_key({:key, "key"}) iex> value = MyCache.encode_value({:value, "value"}) iex> Redix.command!(conn, ["SET", key, value], timeout: 5000) "OK" iex> Redix.command!(conn, ["GET", key]) |> MyCache.decode_value() {:value, "value"} ``` -------------------------------- ### Implement custom JSON serializer for Redis adapter Source: https://hexdocs.pm/nebulex_redis_adapter Example custom serializer using JSON that implements the Nebulex.Adapters.Redis.Serializer behaviour. Useful for JSON serialization, custom compression, different encoding strategies, or integration with external serialization libraries. ```elixir defmodule MyApp.JSONSerializer do @behaviour Nebulex.Adapters.Redis.Serializer @impl true def encode_key(key, _opts), do: JSON.encode!(key) @impl true def encode_value(value, _opts), do: JSON.encode!(value) @impl true def decode_key(key, _opts), do: JSON.decode!(key) @impl true def decode_value(value, _opts), do: JSON.decode!(value) end ``` -------------------------------- ### Deleting and counting keys with delete_all! and count_all! Source: https://hexdocs.pm/nebulex_redis_adapter Demonstrates deleting and counting keys by explicit key list. Both commands return the number of affected keys. ```elixir iex> MyApp.RedisCache.delete_all!(in: ["foo", "bar"]) 2 iex> MyApp.RedisCache.count_all!(in: ["foo", "bar"]) 2 ``` -------------------------------- ### Using fetch_conn!() with Redix.command!() in standalone mode Source: https://hexdocs.pm/nebulex_redis_adapter Shows how to use fetch_conn!() to run custom Redis commands in standalone mode. Each command opens a new connection, so the list operations are not atomic. The output shows the return values of LPUSH and LRANGE. ```elixir iex> MyCache.fetch_conn!() ...> |> Redix.command!(["LPUSH", "mylist", "hello"]) 1 iex> MyCache.fetch_conn!() ...> |> Redix.command!(["LPUSH", "mylist", "world"]) 2 iex> MyCache.fetch_conn!() ...> |> Redix.command!(["LRANGE", "mylist", "0", "-1"]) ["world", "hello"] ``` -------------------------------- ### fetch_conn(opts \\ []) Source: https://hexdocs.pm/nebulex_redis_adapter Fetches a Redix connection from the adapter's connection pool. Accepts options for dynamic caches and cluster modes. Returns a connection that can be used with Redix commands. ```APIDOC ## fetch_conn(opts \\ []) ### Description Fetches a Redix connection from the adapter's connection pool. This allows users to execute custom Redis commands while leveraging the adapter's connection pooling and cluster support. ### Method Function call ### Endpoint `MyCache.fetch_conn(opts \\ [])` ### Parameters #### Options - **`:name`** (atom) - Optional - The name of the cache (for dynamic caches). Defaults to the cache module name. - **`:key`** (term) - Required for `:redis_cluster` and `:client_side_cluster` modes - A cache key used to determine which Redis instance/shard to connect to. In `:redis_cluster` mode, it calculates the hash slot; in `:client_side_cluster` mode, it uses consistent hashing. Not required for `:standalone` mode. - **Redix options** (e.g., `:timeout`, `:telemetry_metadata`) - Optional - Additional options accepted by Redix. ### Request Example ```elixir # Standalone mode conn = MyCache.fetch_conn!() # Cluster mode with key {:ok, conn} = MyCache.fetch_conn(key: "mylist") ``` ### Response #### Success Response Returns a Redix connection (or raises on error if using `fetch_conn!`). #### Response Example ```elixir # Using the connection with Redix commands Redix.command!(conn, ["LPUSH", "mylist", "hello"]) # => 1 Redix.pipeline!(conn, [ ["LPUSH", "mylist", "hello"], ["LPUSH", "mylist", "world"], ["LRANGE", "mylist", "0", "-1"] ]) # => [1, 2, ["world", "hello"]] ``` ``` -------------------------------- ### Standalone Redis cache definition and configuration Source: https://hexdocs.pm/nebulex_redis_adapter Defines a cache module using the Nebulex Redis adapter in standalone mode. The configuration is placed in the application environment, typically in config/config.exs, and specifies the Redis host and port. ```elixir defmodule MyApp.RedisCache do use Nebulex.Cache, otp_app: :my_app, adapter: Nebulex.Adapters.Redis end ``` ```elixir config :my_app, MyApp.RedisCache, conn_opts: [ host: "127.0.0.1", port: 6379 ] ``` -------------------------------- ### Client-side cluster cache definition and configuration Source: https://hexdocs.pm/nebulex_redis_adapter Defines a cache module using the Nebulex Redis adapter and configures it for client-side clustering with multiple nodes, each with its own connection options and pool size. ```elixir defmodule MyApp.ClusteredCache do use Nebulex.Cache, otp_app: :my_app, adapter: Nebulex.Adapters.Redis end ``` ```elixir config :my_app, MyApp.ClusteredCache, mode: :client_side_cluster, client_side_cluster: [ nodes: [ node1: [ pool_size: 10, conn_opts: [ host: "127.0.0.1", port: 9001 ] ], node2: [ pool_size: 4, conn_opts: [ url: "redis://127.0.0.1:9002" ] ], node3: [ conn_opts: [ host: "127.0.0.1", port: 9003 ] ], ... ] ] ``` -------------------------------- ### Configure safe decode options for Redis adapter Source: https://hexdocs.pm/nebulex_redis_adapter Configure safe decode options for the default serializer when decoding data from untrusted sources. The default serializer uses :erlang.binary_to_term/2 for decoding, and setting [:safe] prevents arbitrary atom creation or code execution. ```elixir config :my_app, MyApp.RedisCache, serializer_opts: [ decode_key: [:safe], decode_value: [:safe] ] ``` -------------------------------- ### Redis Cluster cache definition and configuration Source: https://hexdocs.pm/nebulex_redis_adapter Defines a cache module for Redis Cluster using the same adapter as standalone mode. The configuration sets mode to :redis_cluster and provides configuration endpoints for topology discovery, with optional override_master_host for Docker/NAT scenarios. ```elixir defmodule MyApp.RedisClusterCache do use Nebulex.Cache, otp_app: :my_app, adapter: Nebulex.Adapters.Redis end ``` ```elixir config :my_app, MyApp.RedisClusterCache, mode: :redis_cluster, redis_cluster: [ # Configuration endpoints # The client connects to these endpoints to fetch cluster topology # using "CLUSTER SHARDS" (Redis >= 7) or "CLUSTER SLOTS" (Redis < 7). # Multiple endpoints can be provided for redundancy. The adapter will # try each endpoint until it successfully retrieves the topology. configuration_endpoints: [ endpoint1_conn_opts: [ host: "127.0.0.1", port: 6379, # Add the password if 'requirepass' is enabled password: "password" ], endpoint2_conn_opts: [ host: "127.0.0.1", port: 6380, password: "password" ] ], # Optional: Override master host addresses returned by the cluster. # Useful when running Redis in Docker or behind NAT where the # advertised addresses differ from the actual connection addresses. # Defaults to `false`. override_master_host: false ] ``` -------------------------------- ### encode_key/2, encode_value/2, decode_key/2, decode_value/2 Source: https://hexdocs.pm/nebulex_redis_adapter Functions to encode and decode Elixir terms for use with Redis. Useful when working with Elixir terms alongside Redis data types. ```APIDOC ## encode_key(name \\ __MODULE__, key) ### Description Encodes an Elixir term into a string for use as a Redis key. The `name` argument is optional and should be used for dynamic caches (defaults to the cache module). ### Method Function call ### Endpoint `MyCache.encode_key(name \\ __MODULE__, key)` ### Parameters - **`name`** (atom) - Optional - The cache module name (for dynamic caches). Defaults to `__MODULE__`. - **`key`** (term) - Required - The Elixir term to encode. ### Request Example ```elixir key = MyCache.encode_key({:key, "key"}) ``` ### Response Returns the encoded string. --- ## encode_value(name \\ __MODULE__, value) ### Description Encodes an Elixir term into a string for use as a Redis value. Similar to `encode_key` but specific for values. ### Method Function call ### Endpoint `MyCache.encode_value(name \\ __MODULE__, value)` ### Parameters - **`name`** (atom) - Optional - The cache module name (for dynamic caches). Defaults to `__MODULE__`. - **`value`** (term) - Required - The Elixir term to encode. ### Request Example ```elixir value = MyCache.encode_value({:value, "value"}) ``` ### Response Returns the encoded string. --- ## decode_key(name \\ __MODULE__, key) ### Description Decodes a binary (string) back into an Elixir term. The `name` argument is optional and should be used for dynamic caches. ### Method Function call ### Endpoint `MyCache.decode_key(name \\ __MODULE__, key)` ### Parameters - **`name`** (atom) - Optional - The cache module name (for dynamic caches). Defaults to `__MODULE__`. - **`key`** (binary) - Required - The binary to decode. ### Request Example ```elixir decoded_key = MyCache.decode_key(key) ``` ### Response Returns the decoded Elixir term. --- ## decode_value(name \\ __MODULE__, value) ### Description Decodes a binary (string) back into an Elixir term. Similar to `decode_key` but specific for values. ### Method Function call ### Endpoint `MyCache.decode_value(name \\ __MODULE__, value)` ### Parameters - **`name`** (atom) - Optional - The cache module name (for dynamic caches). Defaults to `__MODULE__`. - **`value`** (binary) - Required - The binary to decode. ### Request Example ```elixir decoded_value = MyCache.decode_value(value) ``` ### Response Returns the decoded Elixir term. --- ### Example Usage ```elixir conn = MyCache.fetch_conn!() key = MyCache.encode_key({:key, "key"}) value = MyCache.encode_value({:value, "value"}) Redix.command!(conn, ["SET", key, value], timeout: 5000) # => "OK" Redix.command!(conn, ["GET", key]) |> MyCache.decode_value() # => {:value, "value"} ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.