Skip to content

Commit 17ed5aa

Browse files
authored
Overall fixes and enhancements (#24)
Overall fixes and enhancements - Remove `:nebulex_cluster` dependency - Make dependencies optional
1 parent d4a1e95 commit 17ed5aa

File tree

14 files changed

+350
-202
lines changed

14 files changed

+350
-202
lines changed

.github/workflows/ci.yml

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ jobs:
1212
nebulex_test:
1313
name: 'NebulexRedisAdapter Test (Elixir ${{ matrix.elixir }} OTP ${{ matrix.otp }})'
1414
runs-on: ubuntu-latest
15+
1516
strategy:
1617
matrix:
1718
include:
@@ -26,14 +27,17 @@ jobs:
2627
MIX_ENV: test
2728
NBX_TEST: true
2829
REDIS_CLUSTER_IP: '0.0.0.0'
30+
2931
steps:
3032
- uses: actions/checkout@v2
33+
3134
- name: Start Redis
3235
run: docker-compose up -d
3336
- uses: actions/setup-elixir@v1
3437
with:
3538
otp-version: '${{ matrix.otp }}'
3639
elixir-version: '${{ matrix.elixir }}'
40+
3741
- uses: actions/cache@v1
3842
with:
3943
path: deps
@@ -42,6 +46,7 @@ jobs:
4246
hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}
4347
restore-keys: |
4448
${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-mix-
49+
4550
- uses: actions/cache@v1
4651
with:
4752
path: _build
@@ -50,25 +55,33 @@ jobs:
5055
hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}
5156
restore-keys: |
5257
${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-build-
58+
5359
- name: Install Dependencies
54-
run: mix deps.get
55-
- name: Compile Code
56-
run: mix compile --warnings-as-errors
57-
- name: Check Format
58-
run: mix format --check-formatted
59-
- name: Check Style
60-
run: mix credo --strict
61-
- name: Run Tests
60+
run: |
61+
mix local.hex --force
62+
mix local.rebar --force
63+
mix deps.get
64+
65+
- name: Run style and code consistency checks
66+
run: |
67+
mix compile --warnings-as-errors
68+
mix format --check-formatted
69+
mix credo --strict
70+
71+
- name: Run tests
6272
run: |
6373
epmd -daemon
6474
mix coveralls.github
75+
6576
- uses: actions/cache@v1
6677
with:
6778
path: priv/plts
6879
key: '${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-plt-v1'
6980
restore-keys: |
7081
${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-plt-v1
71-
- name: Run Dialyzer
82+
83+
- name: Run dialyzer
7284
run: mix dialyzer --format short
73-
- name: Report Doc Coverage
85+
86+
- name: Doc Coverage Report
7487
run: MIX_ENV=docs mix inch.report

README.md

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,21 @@ Add `nebulex_redis_adapter` to your list of dependencies in `mix.exs`:
2525
```elixir
2626
defp deps do
2727
[
28-
{:nebulex_redis_adapter, "~> 1.1"}
28+
{:nebulex_redis_adapter, "~> 2.0.0-rc.1"},
29+
{:crc, "~> 0.10"}, #=> Needed when using Redis Cluster
30+
{:jchash, "~> 0.1.2"} #=> NNeeded when using consistent-hashing
2931
]
3032
end
3133
```
3234

35+
In order to give more flexibility and loading only needed dependencies, this
36+
adapter makes all its dependencies as optional. For example:
37+
38+
* `:crc` - Required when using the adapter in mode `:redis_cluster`.
39+
See [Redis Cluster](https://redis.io/topics/cluster-tutorial).
40+
* `:jchash` - Required if you want to use consistent-hashing when using the
41+
adapter in mode `:cluster`.
42+
3343
Then run `mix deps.get` in your shell to fetch the dependencies.
3444

3545
## Usage
@@ -92,7 +102,7 @@ end
92102
The config:
93103

94104
```elixir
95-
config :my_app, MayApp.RedisClusterCache,
105+
config :my_app, MyApp.RedisClusterCache,
96106
# Enable redis_cluster mode
97107
mode: :redis_cluster,
98108

@@ -138,31 +148,13 @@ defmodule MyApp.ClusteredCache do
138148
end
139149
```
140150

141-
The Keyslot module using consistent hashing:
142-
143-
```elixir
144-
defmodule MyApp.ClusteredCache.Keyslot do
145-
use Nebulex.Adapter.Keyslot
146-
147-
@impl true
148-
def hash_slot(key, range) do
149-
key
150-
|> :erlang.phash2()
151-
|> :jchash.compute(range)
152-
end
153-
end
154-
```
155-
156-
And then, within the config:
151+
The config:
157152

158153
```elixir
159-
config :my_app, MayApp.ClusteredCache,
154+
config :my_app, MyApp.ClusteredCache,
160155
# Enable client-side cluster mode
161156
mode: :cluster,
162157

163-
# Keyslot with consistent hashing
164-
keyslot: MyApp.ClusteredCache.Keyslot,
165-
166158
# Nodes config (each node has its own options)
167159
nodes: [
168160
node1: [
@@ -191,11 +183,42 @@ config :my_app, MayApp.ClusteredCache,
191183
]
192184
```
193185

194-
> **NOTE:** It is highly recommendable to provide a consistent hashing
195-
implementation for `Nebulex.Adapter.Keyslot`.
186+
By default, the adapter uses `NebulexRedisAdapter.Cluster.Keyslot` for the
187+
keyslot. Besides, if `:jchash` is defined as dependency, the adapter will use
188+
consistent-hashing automatically.
189+
190+
> **NOTE:** It is highly recommended to define the `:jchash` dependency
191+
when using the adapter in `:cluster` mode.
192+
193+
However, you can also provide your own implementation by implementing the
194+
`Nebulex.Adapter.Keyslot` and set it into the `:keyslot` option. For example:
195+
196+
```elixir
197+
defmodule MyApp.ClusteredCache.Keyslot do
198+
use Nebulex.Adapter.Keyslot
199+
200+
@impl true
201+
def hash_slot(key, range) do
202+
# your implementation goes here
203+
end
204+
end
205+
```
206+
207+
And the config:
208+
209+
```elixir
210+
config :my_app, MyApp.ClusteredCache,
211+
# Enable client-side cluster mode
212+
mode: :cluster,
213+
214+
# Provided Keyslot implementation
215+
keyslot: MyApp.ClusteredCache.Keyslot,
196216

197-
That's all, the rest of the work is done by **NebulexRedisAdapter**
198-
automatically.
217+
# Nodes config (each node has its own options)
218+
nodes: [
219+
...
220+
]
221+
```
199222

200223
### Using `Nebulex.Adapters.Dist`
201224

@@ -311,7 +334,7 @@ to learn more, see the [benchmarks](./benchmarks) directory.
311334
To run the benchmarks:
312335

313336
```
314-
$ mix deps.get && mix run benchmarks/benchmark.exs
337+
$ MIX_ENV=test mix run benchmarks/benchmark.exs
315338
```
316339

317340
> Benchmarks use default Redis options (`host: "127.0.0.1", port: 6379`).
@@ -329,16 +352,8 @@ When submitting a pull request you should not update the [CHANGELOG.md](CHANGELO
329352
and also make sure you test your changes thoroughly, include unit tests
330353
alongside new or changed code.
331354

332-
Before to submit a PR it is highly recommended to run:
333-
334-
* `export NBX_TEST=true` to fetch Nebulex from GH directly and be able to
335-
re-use shared tests.
336-
* `mix coveralls.html && open cover/excoveralls.html` to run tests and check
337-
out code coverage (expected 100%).
338-
* `mix format && mix credo --strict` to format your code properly and find code
339-
style issues
340-
* `mix dialyzer` to run dialyzer for type checking; might take a while on the
341-
first invocation
355+
Before to submit a PR it is highly recommended to run `mix check` and ensure
356+
all checks run successfully.
342357

343358
## Copyright and License
344359

benchmarks/benchmark.exs

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ keys = Enum.to_list(1..10_000)
1414
bulk = for x <- 1..100, do: {x, x}
1515

1616
# init caches
17-
Enum.each(1..5000, &BenchCache.set(&1, &1))
17+
Enum.each(1..5000, &BenchCache.put(&1, &1))
1818

1919
inputs = %{
2020
"Redis Cache" => BenchCache
@@ -24,23 +24,20 @@ benchmarks = %{
2424
"get" => fn {cache, random} ->
2525
cache.get(random)
2626
end,
27-
"set" => fn {cache, random} ->
28-
cache.set(random, random)
27+
"get_all" => fn {cache, _random} ->
28+
cache.get_all([1, 2, 3, 4, 5, 6, 7, 8, 9])
2929
end,
30-
"add" => fn {cache, random} ->
31-
cache.add(random, random)
30+
"put" => fn {cache, random} ->
31+
cache.put(random, random)
32+
end,
33+
"put_new" => fn {cache, random} ->
34+
cache.put_new(random, random)
3235
end,
3336
"replace" => fn {cache, random} ->
3437
cache.replace(random, random)
3538
end,
36-
"add_or_replace!" => fn {cache, random} ->
37-
cache.add_or_replace!(random, random)
38-
end,
39-
"get_many" => fn {cache, _random} ->
40-
cache.get_many([1, 2, 3, 4, 5, 6, 7, 8, 9])
41-
end,
42-
"set_many" => fn {cache, _random} ->
43-
cache.set_many(bulk)
39+
"put_all" => fn {cache, _random} ->
40+
cache.put_all(bulk)
4441
end,
4542
"delete" => fn {cache, random} ->
4643
cache.delete(random)
@@ -54,35 +51,26 @@ benchmarks = %{
5451
"size" => fn {cache, _random} ->
5552
cache.size()
5653
end,
57-
"object_info" => fn {cache, random} ->
58-
cache.object_info(random, :ttl)
54+
"ttl" => fn {cache, random} ->
55+
cache.ttl(random)
5956
end,
6057
"expire" => fn {cache, random} ->
61-
cache.expire(random, 1)
58+
cache.expire(random, 1000)
59+
end,
60+
"incr" => fn {cache, _random} ->
61+
cache.incr(:counter, 1)
62+
end,
63+
"update" => fn {cache, random} ->
64+
cache.update(random, 1, &Kernel.+(&1, 1))
6265
end,
6366
"get_and_update" => fn {cache, random} ->
6467
cache.get_and_update(random, fn
6568
nil -> {nil, 1}
6669
val -> {val, val * 2}
6770
end)
6871
end,
69-
"update" => fn {cache, random} ->
70-
cache.update(random, 1, &Kernel.+(&1, 1))
71-
end,
72-
"update_counter" => fn {cache, _random} ->
73-
cache.update_counter(:counter, 1)
74-
end,
7572
"all" => fn {cache, _random} ->
7673
cache.all()
77-
end,
78-
"transaction" => fn {cache, random} ->
79-
cache.transaction(
80-
fn ->
81-
cache.update(random, 1, &Kernel.+(&1, 1))
82-
:ok
83-
end,
84-
keys: [random]
85-
)
8674
end
8775
}
8876

@@ -92,23 +80,14 @@ Benchee.run(
9280
before_scenario: fn cache ->
9381
{cache, Enum.random(keys)}
9482
end,
95-
console: [
96-
comparison: false,
97-
extended_statistics: true
98-
],
9983
formatters: [
100-
Benchee.Formatters.Console,
101-
Benchee.Formatters.HTML
102-
],
103-
formatter_options: [
104-
html: [
105-
auto_open: false
106-
]
84+
{Benchee.Formatters.Console, comparison: false, extended_statistics: true},
85+
{Benchee.Formatters.HTML, extended_statistics: true, auto_open: false}
10786
],
10887
print: [
10988
fast_warning: false
11089
]
11190
)
11291

11392
# stop caches s
114-
if Process.alive?(local), do: BenchCache.stop(local)
93+
if Process.alive?(local), do: Supervisor.stop(local)

config/test.exs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ config :nebulex_redis_adapter, NebulexRedisAdapter.TestCache.Standalone,
1010
# Redis test cache
1111
config :nebulex_redis_adapter, NebulexRedisAdapter.TestCache.Cluster,
1212
mode: :cluster,
13-
keyslot: NebulexRedisAdapter.TestCache.Keyslot,
1413
nodes: [
1514
node1: [
1615
conn_opts: [

0 commit comments

Comments
 (0)