diff --git a/lib/cacheman.ex b/lib/cacheman.ex index d08817e..5b00868 100644 --- a/lib/cacheman.ex +++ b/lib/cacheman.ex @@ -81,7 +81,7 @@ defmodule Cacheman do use GenServer require Logger - @default_put_options [ttl: :infinity] + @default_put_options [ttl: :infinity, timeout: 5_000] # # Cacheman API @@ -149,7 +149,9 @@ defmodule Cacheman do Nil values are not storrable in the cache. """ - def put(name, key, value, put_opts \\ @default_put_options) do + def put(name, key, value, put_opts \\ []) do + put_opts = @default_put_options |> Keyword.merge(put_opts) + if value == nil do {:ok, nil} else @@ -173,7 +175,9 @@ defmodule Cacheman do @spec put_batch(String.t(), list(key_value_pair), list()) :: {:ok, integer} | {:error, Redix.Protocol.ParseError | Redix.Error | Redix.ConnectionError} - def put_batch(name, key_value_pairs, put_opts \\ @default_put_options) do + def put_batch(name, key_value_pairs, put_opts \\ []) do + put_opts = @default_put_options |> Keyword.merge(put_opts) + GenServer.call(full_process_name(name), {:put_batch, key_value_pairs, put_opts}) end diff --git a/lib/cacheman/backend/redis.ex b/lib/cacheman/backend/redis.ex index 794e00b..12da7d9 100644 --- a/lib/cacheman/backend/redis.ex +++ b/lib/cacheman/backend/redis.ex @@ -41,23 +41,25 @@ defmodule Cacheman.Backend.Redis do end) end - def put(conn, key, value, ttl) do + def put(conn, key, value, opts) do :poolboy.transaction(conn, fn c -> - case Redix.command(c, ["SET", key, value] ++ ttl_command(ttl)) do + case Redix.command(c, ["SET", key, value] ++ ttl_command(opts[:ttl]), + timeout: opts[:timeout] + ) do {:ok, "OK"} -> {:ok, value} e -> e end end) end - def put_batch(conn, key_value_pairs, ttl) when is_list(key_value_pairs) do + def put_batch(conn, key_value_pairs, opts) when is_list(key_value_pairs) do list_of_commands = Enum.map(key_value_pairs, fn {key, value} -> - ["SET", key, value] ++ ttl_command(ttl) + ["SET", key, value] ++ ttl_command(opts[:ttl]) end) :poolboy.transaction(conn, fn c -> - Redix.pipeline(c, list_of_commands) + Redix.pipeline(c, list_of_commands, timeout: opts[:timeout]) end) end @@ -73,6 +75,6 @@ defmodule Cacheman.Backend.Redis do end) end - def ttl_command(ttl: :infinity), do: [] - def ttl_command(ttl: ttl), do: ["PX", "#{ttl}"] + def ttl_command(:infinity), do: [] + def ttl_command(ttl), do: ["PX", "#{ttl}"] end diff --git a/mix.exs b/mix.exs index 2aaa326..e3f8b24 100644 --- a/mix.exs +++ b/mix.exs @@ -22,6 +22,7 @@ defmodule ExCacheman.MixProject do defp deps do [ {:redix, "~> 0.10.5"}, + {:mock, "~> 0.3.0", only: :test}, {:poolboy, "~> 1.5"} ] end diff --git a/mix.lock b/mix.lock index 329f17f..9f95ad2 100644 --- a/mix.lock +++ b/mix.lock @@ -1,4 +1,6 @@ %{ + "meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"}, + "mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, "redix": {:hex, :redix, "0.10.5", "2240a74cc0a236e0e0d8ebf2d20674151d59e9965342879d36cf856d93099f01", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "37774c9753a4b3bb7cb263b5996357ffc319129c70bb698f5cc02d676c704b81"}, "telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"}, diff --git a/test/cacheman_test.exs b/test/cacheman_test.exs index 5f7ff00..6c4f0e0 100644 --- a/test/cacheman_test.exs +++ b/test/cacheman_test.exs @@ -1,5 +1,6 @@ defmodule CachemanTest do use ExUnit.Case + import Mock doctest Cacheman setup_all do @@ -72,6 +73,14 @@ defmodule CachemanTest do assert {:ok, nil} = Cacheman.get(:good, key2) end + test "put_batch with custom timeout" do + timeout = 10_000 + + with_mock Redix, [], pipeline: fn _, _, opts -> assert opts[:timeout] == timeout end do + Cacheman.put_batch(:good, [{"test_key", "test_value"}], timeout: timeout) + end + end + test "get_batch" do key1 = "test-#{:rand.uniform(10_000)}" key2 = "test-#{:rand.uniform(10_000)}"