diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9f0cce..ea7e96f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,14 +38,14 @@ jobs: - otp_version: 25 elixir_version: 1.12.3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: erlef/setup-beam@v1 with: otp-version: ${{matrix.otp_version}} elixir-version: ${{matrix.elixir_version}} - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | deps diff --git a/LICENSE.md b/LICENSE.md index 6ccc2e1..2ec6e97 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -2,7 +2,7 @@ The MIT License =============== -Copyright 2017 Shane Kilkelly +Copyright 2023 June Kelly Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 296b209..ec29d6a 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Configure the `:hammer` application to use the Redis backend: ```elixir config :hammer, backend: {Hammer.Backend.Redis, [delete_buckets_timeout: 10_0000, + key_prefix: "my_application:rate_limiter", expiry_ms: 60_000 * 60 * 2, redix_config: [host: "localhost", port: 6379]]} @@ -41,6 +42,7 @@ the redis_url will be used first. ```elixir config :hammer, backend: {Hammer.Backend.Redis, [delete_buckets_timeout: 10_0000, + key_prefix: "my_application:rate_limiter", expiry_ms: 60_000 * 60 * 2, redis_url: "redis://HOST:PORT"]} ``` diff --git a/lib/hammer_backend_redis.ex b/lib/hammer_backend_redis.ex index 3bf6760..e309793 100644 --- a/lib/hammer_backend_redis.ex +++ b/lib/hammer_backend_redis.ex @@ -17,6 +17,7 @@ defmodule Hammer.Backend.Redis do used to set TTL on Redis keys. This configuration is mandatory. - `redix_config`: Keyword list of options to the `Redix` redis client, also aliased to `redis_config` + - `key_prefix`: The prefix to use for all the redis keys (defaults to "Hammer:Redis:") - `redis_url`: String url of redis server to connect to (optional, invokes Redix.start_link/2) """ @@ -98,6 +99,8 @@ defmodule Hammer.Backend.Redis do raise RuntimeError, "Missing required config: expiry_ms" end + key_prefix = Keyword.get(args, :key_prefix, "Hammer:Redis:") + redix_config = Keyword.get( args, @@ -124,6 +127,7 @@ defmodule Hammer.Backend.Redis do expiry_ms: expiry_ms, delete_buckets_timeout: delete_buckets_timeout, cluster_nodes: cluster_nodes + key_prefix: key_prefix }} end @@ -132,15 +136,15 @@ defmodule Hammer.Backend.Redis do {:stop, :normal, :ok, state} end - def handle_call({:count_hit, key, now, increment}, _from, %{redix: r} = state) do + def handle_call({:count_hit, key, now, increment}, _from, state) do expiry = get_expiry(state) - {result, node_conn} = do_count_hit(r, key, now, increment, expiry) + result = do_count_hit(state, key, now, increment, expiry) state_with_cluster_nodes = append_cluster_node(state, node_conn) {:reply, result, state_with_cluster_nodes} end def handle_call({:get_bucket, key}, _from, %{redix: r} = state) do - redis_key = make_redis_key(key) + redis_key = make_redis_key(state, key) command = ["HMGET", redis_key, "count", "created", "updated"] result = @@ -162,7 +166,7 @@ defmodule Hammer.Backend.Redis do end def handle_call({:delete_buckets, id}, _from, %{redix: r} = state) do - redis_key_pattern = make_redis_key_pattern(id) + redis_key_pattern = make_redis_key_pattern(state, id) cluster_nodes_conn = MapSet.to_list(state.cluster_nodes) result = do_delete_buckets(r, redis_key_pattern, 0, 0, cluster_nodes_conn) @@ -245,8 +249,8 @@ defmodule Hammer.Backend.Redis do # we are using the first method described (called bucketing) # in https://www.youtube.com/watch?v=CRGPbCbRTHA # but we add the 'created' and 'updated' meta information fields. - defp do_count_hit(r, key, now, increment, expiry) do - redis_key = make_redis_key(key) + defp do_count_hit(%{redix: r} = state, key, now, increment, expiry) do + redis_key = make_redis_key(state, key) cmds = [ ["MULTI"], @@ -307,12 +311,12 @@ defmodule Hammer.Backend.Redis do execute_pipeline(conn, pipeline_cmds, conn) end - defp make_redis_key({bucket, id}) do - "Hammer:Redis:#{id}:#{bucket}" + defp make_redis_key(%{key_prefix: key_prefix}, {bucket, id}) do + "#{key_prefix}#{id}:#{bucket}" end - defp make_redis_key_pattern(id) do - "Hammer:Redis:#{id}:*" + defp make_redis_key_pattern(%{key_prefix: key_prefix}, id) do + "#{key_prefix}#{id}:*" end defp get_expiry(state) do diff --git a/mix.exs b/mix.exs index a3f5f97..9bc890b 100644 --- a/mix.exs +++ b/mix.exs @@ -48,7 +48,7 @@ defmodule HammerBackendRedis.Mixfile do defp package do [ name: :hammer_backend_redis, - maintainers: ["Emmanuel Pinault", "Shane Kilkelly (shane@kilkelly.me)"], + maintainers: ["Emmanuel Pinault", "June Kelly"], licenses: ["MIT"], links: %{ "GitHub" => "https://github.com/ExHammer/hammer-backend-redis", diff --git a/mix.lock b/mix.lock index dd214b1..5cdb3e4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,20 +1,33 @@ %{ + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, + "credo": {:hex, :credo, "1.7.3", "05bb11eaf2f2b8db370ecaa6a6bda2ec49b2acd5e0418bc106b73b07128c0436", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "35ea675a094c934c22fb1dca3696f3c31f2728ae6ef5a53b5d648c11180a4535"}, + "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, + "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, + "ex_doc": {:hex, :ex_doc, "0.31.1", "8a2355ac42b1cc7b2379da9e40243f2670143721dd50748bf6c3b1184dae2089", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3178c3a407c557d8343479e1ff117a96fd31bafe52a039079593fb0524ef61b0"}, + "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, + "hammer": {:hex, :hammer, "6.1.0", "f263e3c3e9946bd410ea0336b2abe0cb6260af4afb3a221e1027540706e76c55", [:make, :mix], [{:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm", "b47e415a562a6d072392deabcd58090d8a41182cf9044cdd6b0d0faaaf68ba57"}, + "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"}, "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, - "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, - "dialyxir": {:hex, :dialyxir, "1.2.0", "58344b3e87c2e7095304c81a9ae65cb68b613e28340690dfe1a5597fd08dec37", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "61072136427a851674cab81762be4dbeae7679f85b1272b6d25c3a839aff8463"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"}, + "credo": {:hex, :credo, "1.7.0", "6119bee47272e85995598ee04f2ebbed3e947678dee048d10b5feca139435f75", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "6839fcf63d1f0d1c0f450abc8564a57c43d644077ab96f2934563e68b8a769d7"}, + "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_doc": {:hex, :ex_doc, "0.29.1", "b1c652fa5f92ee9cf15c75271168027f92039b3877094290a75abcaac82a9f77", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "b7745fa6374a36daf484e2a2012274950e084815b936b1319aeebcf7809574f6"}, + "ex_doc": {:hex, :ex_doc, "0.31.1", "8a2355ac42b1cc7b2379da9e40243f2670143721dd50748bf6c3b1184dae2089", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3178c3a407c557d8343479e1ff117a96fd31bafe52a039079593fb0524ef61b0"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "hammer": {:hex, :hammer, "6.1.0", "f263e3c3e9946bd410ea0336b2abe0cb6260af4afb3a221e1027540706e76c55", [:make, :mix], [{:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm", "b47e415a562a6d072392deabcd58090d8a41182cf9044cdd6b0d0faaaf68ba57"}, "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, - "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, + "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"}, "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"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, + "mock": {:hex, :mock, "0.3.8", "7046a306b71db2488ef54395eeb74df0a7f335a7caca4a3d3875d1fc81c884dd", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "7fa82364c97617d79bb7d15571193fc0c4fe5afd0c932cef09426b3ee6fe2022"}, + "nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, - "redix": {:hex, :redix, "1.2.0", "0d7eb3ccb7b82c461a6ea28b65c2c04486093d816dd6d901a09164800e004df1", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e1e0deb14599da07c77e66956a12863e85ee270ada826804a0ba8e61657e22a3"}, - "telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"}, + "redix": {:hex, :redix, "1.3.0", "f4121163ff9d73bf72157539ff23b13e38422284520bb58c05e014b19d6f0577", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:nimble_options, "~> 0.5.0 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "60d483d320c77329c8cbd3df73007e51b23f3fae75b7693bc31120d83ab26131"}, + "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, } diff --git a/test/hammer_backend_redis_test.exs b/test/hammer_backend_redis_test.exs index b84e763..f0153a3 100644 --- a/test/hammer_backend_redis_test.exs +++ b/test/hammer_backend_redis_test.exs @@ -9,25 +9,29 @@ defmodule HammerBackendRedisTest do %{redix: redix} = :sys.get_state(pid) assert {:ok, "OK"} = Redix.command(redix, ["FLUSHALL"]) - {:ok, [pid: pid, redix: redix]} + {:ok, [pid: pid, redix: redix, key_prefix: Keyword.get(config, :key_prefix, "Hammer:Redis:")]} end - test "count_hit, insert", %{pid: pid, redix: redix} do + test "count_hit, insert", %{pid: pid, redix: redix, key_prefix: key_prefix} do bucket = 1 id = "one" bucket_key = {bucket, id} now = 123 now_str = Integer.to_string(now) - assert {:ok, 0} = Redix.command(redix, ["EXISTS", make_redis_key(bucket_key)]) + assert {:ok, 0} = Redix.command(redix, ["EXISTS", make_redis_key(key_prefix, bucket_key)]) assert {:ok, 1} == Backend.Redis.count_hit(pid, bucket_key, now) - assert {:ok, 1} = Redix.command(redix, ["EXISTS", make_redis_key(bucket_key)]) + assert {:ok, 1} = Redix.command(redix, ["EXISTS", make_redis_key(key_prefix, bucket_key)]) assert {:ok, ["count", "1", "created", ^now_str, "updated", ^now_str]} = - Redix.command(redix, ["HGETALL", make_redis_key(bucket_key)]) + Redix.command(redix, ["HGETALL", make_redis_key(key_prefix, bucket_key)]) end - test "count_hit, insert, with custom increment", %{pid: pid, redix: redix} do + test "count_hit, insert, with custom increment", %{ + pid: pid, + redix: redix, + key_prefix: key_prefix + } do bucket = 1 id = "one" bucket_key = {bucket, id} @@ -37,13 +41,13 @@ defmodule HammerBackendRedisTest do inc_str = Integer.to_string(inc) assert {:ok, inc} == Backend.Redis.count_hit(pid, bucket_key, now, inc) - assert {:ok, 1} = Redix.command(redix, ["EXISTS", make_redis_key(bucket_key)]) + assert {:ok, 1} = Redix.command(redix, ["EXISTS", make_redis_key(key_prefix, bucket_key)]) assert {:ok, ["count", ^inc_str, "created", ^now_str, "updated", ^now_str]} = - Redix.command(redix, ["HGETALL", make_redis_key(bucket_key)]) + Redix.command(redix, ["HGETALL", make_redis_key(key_prefix, bucket_key)]) end - test "count_hit, update", %{pid: pid, redix: redix} do + test "count_hit, update", %{pid: pid, redix: redix, key_prefix: key_prefix} do # 1. set-up bucket = 1 id = "one" @@ -54,14 +58,14 @@ defmodule HammerBackendRedisTest do now_after_str = Integer.to_string(now_after) assert {:ok, 1} == Backend.Redis.count_hit(pid, bucket_key, now_before) - assert {:ok, 1} = Redix.command(redix, ["EXISTS", make_redis_key(bucket_key)]) + assert {:ok, 1} = Redix.command(redix, ["EXISTS", make_redis_key(key_prefix, bucket_key)]) # 2. function call under test: count == 2 assert {:ok, 2} == Backend.Redis.count_hit(pid, bucket_key, now_after) - assert {:ok, 1} = Redix.command(redix, ["EXISTS", make_redis_key(bucket_key)]) + assert {:ok, 1} = Redix.command(redix, ["EXISTS", make_redis_key(key_prefix, bucket_key)]) assert {:ok, ["count", "2", "created", ^now_before_str, "updated", ^now_after_str]} = - Redix.command(redix, ["HGETALL", make_redis_key(bucket_key)]) + Redix.command(redix, ["HGETALL", make_redis_key(key_prefix, bucket_key)]) end test "get_bucket", %{pid: pid} do @@ -163,7 +167,7 @@ defmodule HammerBackendRedisTest do assert 1_000 == length(keys) end - defp make_redis_key({bucket, id}) do - "Hammer:Redis:#{id}:#{bucket}" + defp make_redis_key(prefix, {bucket, id}) do + "#{prefix}#{id}:#{bucket}" end end