Skip to content

Commit 3ed99eb

Browse files
committed
[#65] Migrate adapter to Nebulex V3
1 parent 9106372 commit 3ed99eb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2867
-2532
lines changed

.formatter.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ locals_without_parens = [
55
]
66

77
[
8+
import_deps: [:nebulex],
89
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
910
line_length: 100,
1011
locals_without_parens: locals_without_parens,

.github/workflows/ci.yml

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,26 @@ on:
1111
jobs:
1212
nebulex_test:
1313
name: >-
14-
NebulexRedisAdapter Test (Elixir ${{ matrix.elixir }} / OTP ${{ matrix.otp }} /
14+
Nebulex.Adapters.Redis Test (Elixir ${{ matrix.elixir }} / OTP ${{ matrix.otp }} /
1515
OS ${{ matrix.os }})
1616
runs-on: ${{ matrix.os }}
1717

1818
strategy:
1919
matrix:
2020
include:
21-
- elixir: 1.17.x
21+
- elixir: 1.18.x
2222
otp: 27.x
2323
os: 'ubuntu-latest'
24-
style: true
24+
lint: true
2525
coverage: true
2626
dialyzer: true
27-
- elixir: 1.17.x
28-
otp: 26.x
29-
os: 'ubuntu-latest'
30-
- elixir: 1.16.x
31-
otp: 26.x
32-
os: 'ubuntu-latest'
3327
- elixir: 1.15.x
3428
otp: 25.x
3529
os: 'ubuntu-latest'
36-
- elixir: 1.14.x
37-
otp: 23.x
38-
os: 'ubuntu-20.04'
3930

4031
env:
4132
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
33+
CODECOV_TOKEN: '${{ secrets.CODECOV_TOKEN }}'
4234
MIX_ENV: test
4335
NEBULEX_PATH: nebulex
4436
REDIS_CLUSTER_IP: '0.0.0.0'
@@ -82,25 +74,40 @@ jobs:
8274
mix deps.get
8375
if: ${{ steps.mix-cache.outputs.cache-hit != 'true' }}
8476

85-
- name: Compile code
77+
- name: Compile deps
78+
run: mix deps.compile
79+
80+
- name: Check unused dependencies
81+
run: mix deps.unlock --check-unused
82+
if: ${{ matrix.lint }}
83+
84+
- name: Compile lint
8685
run: mix compile --warnings-as-errors
86+
if: ${{ matrix.lint }}
8787

8888
- name: Run style and code consistency checks
8989
run: |
9090
mix format --check-formatted
9191
mix credo --strict
92-
if: ${{ matrix.style }}
92+
if: ${{ matrix.lint }}
9393

9494
- name: Run tests
9595
run: |
9696
epmd -daemon
97-
mix test --trace
97+
mix test --exclude nebulex_test
9898
if: ${{ !matrix.coverage }}
9999

100100
- name: Run tests with coverage
101101
run: |
102102
epmd -daemon
103-
mix coveralls.github
103+
mix coveralls.json --exclude nebulex_test
104+
if: ${{ matrix.coverage }}
105+
106+
- name: Upload coverage reports to Codecov
107+
uses: codecov/codecov-action@v5
108+
with:
109+
fail_ci_if_error: true
110+
flags: unittests-elixir-${{ matrix.elixir }}-otp-${{ matrix.otp }}
104111
if: ${{ matrix.coverage }}
105112

106113
- name: Restore PLT Cache

.tool-versions

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
elixir 1.17.0-otp-27
2-
erlang 27.0
1+
elixir 1.18.3-otp-27
2+
erlang 27.3.2

CHANGELOG.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@ All notable changes to this project will be documented in this file.
44

55
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [v2.4.2](https://github.com/cabol/nebulex_redis_adapter/tree/v2.4.2) (2024-11-01)
8-
9-
[Full Changelog](https://github.com/cabol/nebulex_redis_adapter/compare/v2.4.1...v2.4.2)
10-
11-
**Closed issues:**
12-
13-
- `NebulexRedisAdapter.RedisCluster.Keyslot` incorrectly computes slot for
14-
hash tags.
15-
[#64](https://github.com/cabol/nebulex_redis_adapter/issues/64)
16-
177
## [v2.4.1](https://github.com/cabol/nebulex_redis_adapter/tree/v2.4.1) (2024-09-01)
188

199
[Full Changelog](https://github.com/cabol/nebulex_redis_adapter/compare/v2.4.0...v2.4.1)

README.md

Lines changed: 42 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
# NebulexRedisAdapter
1+
# Nebulex.Adapters.Redis
22
> Nebulex adapter for Redis (including [Redis Cluster][redis_cluster] support).
33
4-
![CI](https://github.com/cabol/nebulex_redis_adapter/workflows/CI/badge.svg)
5-
[![Coverage Status](https://coveralls.io/repos/github/cabol/nebulex_redis_adapter/badge.svg?branch=master)](https://coveralls.io/github/cabol/nebulex_redis_adapter?branch=master)
4+
![CI](https://github.com/elixir-nebulex/nebulex_redis_adapter/workflows/CI/badge.svg)
5+
[![Codecov](https://codecov.io/gh/elixir-nebulex/nebulex_redis_adapter/branch/v3.0.0-dev/graph/badge.svg)](https://codecov.io/gh/elixir-nebulex/nebulex_redis_adapter/branch/v3.0.0-dev/graph/badge.svg)
66
[![Hex Version](https://img.shields.io/hexpm/v/nebulex_redis_adapter.svg)](https://hex.pm/packages/nebulex_redis_adapter)
7-
[![Docs](https://img.shields.io/badge/docs-hexpm-blue.svg)](https://hexdocs.pm/nebulex_redis_adapter)
7+
[![Documentation](https://img.shields.io/badge/Documentation-ff69b4)](https://hexdocs.pm/nebulex_redis_adapter)
8+
9+
## About
810

911
This adapter uses [Redix](https://github.com/whatyouhide/redix); a Redis driver
1012
for Elixir.
@@ -15,8 +17,8 @@ next sections.
1517
See also [online documentation][nbx_redis_adapter]
1618
and [Redis cache example][nbx_redis_example].
1719

18-
[nbx_redis_adapter]: http://hexdocs.pm/nebulex_redis_adapter/NebulexRedisAdapter.html
19-
[nbx_redis_example]: https://github.com/cabol/nebulex_examples/tree/master/redis_cache
20+
[nbx_redis_adapter]: http://hexdocs.pm/nebulex_redis_adapter/Nebulex.Adapters.Redis.html
21+
[nbx_redis_example]: https://github.com/elixir-nebulex/nebulex_examples/tree/master/redis_cache
2022
[redis_cluster]: https://redis.io/topics/cluster-tutorial
2123

2224
## Installation
@@ -26,9 +28,9 @@ Add `:nebulex_redis_adapter` to your list of dependencies in `mix.exs`:
2628
```elixir
2729
defp deps do
2830
[
29-
{:nebulex_redis_adapter, "~> 2.3"},
30-
{:crc, "~> 0.10"}, #=> Needed when using Redis Cluster
31-
{:jchash, "~> 0.1.4"} #=> Needed when using consistent-hashing
31+
{:nebulex_redis_adapter, "~> 3.0.0-rc.0"},
32+
{:crc, "~> 0.10"}, #=> Needed when using `:redis_cluster` mode
33+
{:ex_hash_ring, "~> 6.0"} #=> Needed when using `:client_side_cluster` mode
3234
]
3335
end
3436
```
@@ -38,8 +40,8 @@ needed ones. For example:
3840

3941
* `:crc` - Required when using the adapter in mode `:redis_cluster`.
4042
See [Redis Cluster][redis_cluster].
41-
* `:jchash` - Required if you want to use consistent-hashing when using the
42-
adapter in mode `:client_side_cluster`.
43+
* `:ex_hash_ring` - Required when using the adapter in mode
44+
`:client_side_cluster`.
4345

4446
Then run `mix deps.get` to fetch the dependencies.
4547

@@ -51,7 +53,7 @@ After installing, we can define our cache to use Redis adapter as follows:
5153
defmodule MyApp.RedisCache do
5254
use Nebulex.Cache,
5355
otp_app: :my_app,
54-
adapter: NebulexRedisAdapter
56+
adapter: Nebulex.Adapters.Redis
5557
end
5658
```
5759

@@ -69,15 +71,15 @@ config :my_app, MyApp.RedisCache,
6971

7072
Since this adapter is implemented by means of `Redix`, it inherits the same
7173
options, including regular Redis options and connection options as well. For
72-
more information about the options, please check out `NebulexRedisAdapter`
74+
more information about the options, please check out `Nebulex.Adapters.Redis`
7375
module and also [Redix](https://github.com/whatyouhide/redix).
7476

7577
See also [Redis cache example][nbx_redis_example].
7678

7779
## Distributed Caching
7880

7981
There are different ways to support distributed caching when using
80-
**NebulexRedisAdapter**.
82+
**Nebulex.Adapters.Redis**.
8183

8284
### Redis Cluster
8385

@@ -95,7 +97,7 @@ Then we can define our cache which will use **Redis Cluster**:
9597
defmodule MyApp.RedisClusterCache do
9698
use Nebulex.Cache,
9799
otp_app: :my_app,
98-
adapter: NebulexRedisAdapter
100+
adapter: Nebulex.Adapters.Redis
99101
end
100102
```
101103

@@ -127,20 +129,20 @@ The pool of connections to the different master nodes is automatically
127129
configured by the adapter once it gets the cluster slots info.
128130

129131
> This one could be the easiest and recommended way for distributed caching
130-
using Redis and **NebulexRedisAdapter**.
132+
using Redis and **Nebulex.Adapters.Redis**.
131133

132-
### Client-side Cluster based on Sharding
134+
### Client-side Cluster
133135

134-
**NebulexRedisAdapter** also brings with a simple client-side cluster
135-
implementation based on Sharding distribution model.
136+
**Nebulex.Adapters.Redis** also brings with a simple client-side cluster
137+
implementation based on sharding distribution model.
136138

137139
We define our cache normally:
138140

139141
```elixir
140142
defmodule MyApp.ClusteredCache do
141143
use Nebulex.Cache,
142144
otp_app: :my_app,
143-
adapter: NebulexRedisAdapter
145+
adapter: Nebulex.Adapters.Redis
144146
end
145147
```
146148

@@ -182,101 +184,41 @@ config :my_app, MyApp.ClusteredCache,
182184
]
183185
```
184186

185-
By default, the adapter uses `NebulexRedisAdapter.ClientCluster.Keyslot` for the
186-
keyslot. Besides, if `:jchash` is defined as dependency, the adapter will use
187-
consistent-hashing automatically.
188-
189-
> **NOTE:** It is highly recommended to define the `:jchash` dependency
190-
when using the adapter in `:client_side_cluster` mode.
191-
192-
However, you can also provide your own implementation by implementing the
193-
`Nebulex.Adapter.Keyslot` and set it into the `:keyslot` option. For example:
194-
195-
```elixir
196-
defmodule MyApp.ClusteredCache.Keyslot do
197-
use Nebulex.Adapter.Keyslot
198-
199-
@impl true
200-
def hash_slot(key, range) do
201-
# your implementation goes here
202-
end
203-
end
204-
```
205-
206-
And the config:
207-
208-
```elixir
209-
config :my_app, MyApp.ClusteredCache,
210-
# Enable client-side cluster mode
211-
mode: :client_side_cluster,
212-
213-
client_side_cluster: [
214-
# Provided Keyslot implementation
215-
keyslot: MyApp.ClusteredCache.Keyslot,
216-
217-
# Nodes config (each node has its own options)
218-
nodes: [
219-
...
220-
]
221-
]
222-
```
223-
224-
### Using `Nebulex.Adapters.Partitioned`
225-
226-
Another simple option is to use the `Nebulex.Adapters.Partitioned` and set as
227-
local cache the `NebulexRedisAdapter`. The idea here is each Elixir node running
228-
the distributed cache (`Nebulex.Adapters.Partitioned`) will have as local
229-
backend or cache a Redis instance (handled by `NebulexRedisAdapter`).
230-
231-
232-
This example shows how the setup a distributed cache using
233-
`Nebulex.Adapters.Partitioned` and `NebulexRedisAdapter`:
234-
235-
```elixir
236-
defmodule MyApp.DistributedCache do
237-
use Nebulex.Cache,
238-
otp_app: :my_app,
239-
adapter: Nebulex.Adapters.Partitioned,
240-
primary_storage_adapter: NebulexRedisAdapter
241-
end
242-
```
243-
244187
### Using a Redis Proxy
245188

246189
The other option is to use a proxy, like [Envoy proxy][envoy] or
247190
[Twemproxy][twemproxy] on top of Redis. In this case, the proxy does the
248-
distribution work, and from the adparter's side (**NebulexRedisAdapter**),
191+
distribution work, and from the adparter's side (**Nebulex.Adapters.Redis**),
249192
it would be only configuration. Instead of connect the adapter against the
250193
Redis nodes, we connect it against the proxy nodes, this means, in the config,
251194
we setup the pool with the host and port pointing to the proxy.
252195

253196
[envoy]: https://www.envoyproxy.io/
254197
[twemproxy]: https://github.com/twitter/twemproxy
255198

256-
## Running Redis commands and/or pipelines
199+
## Using the adapter as a Redis client
257200

258-
Since `NebulexRedisAdapter` works on top of `Redix` and provides features like
259-
connection pools and "Redis Cluster" support, it may be seen also as a sort of
260-
Redis client, but it is meant to be used mainly with the Nebulex cache API.
261-
However, Redis API is quite extensive and there are a lot of useful commands
262-
we may want to run taking advantage of the `NebulexRedisAdapter` features.
263-
Therefore, the adapter injects two additional/extended functions to the
264-
defined cache: `command!/2` and `pipeline!/2`.
201+
Since the Redis adapter works on top of `Redix` and provides features like
202+
connection pools, "Redis Cluster", etc., it may also work as a Redis client.
203+
The Redis API is quite extensive, and there are many useful commands we may
204+
want to run, leveraging the Redis adapter features. Therefore, the adapter
205+
provides additional functions to do so.
265206

266207
```elixir
267-
iex> MyCache.command!(["LPUSH", "mylist", "world"], key: "mylist")
208+
iex> conn = MyCache.fetch_conn!()
209+
iex> Redix.command!(conn, ["LPUSH", "mylist", "world"])
268210
1
269-
iex> MyCache.command!(["LPUSH", "mylist", "hello"], key: "mylist")
211+
iex> Redix.command!(conn, ["LPUSH", "mylist", "hello"])
270212
2
271-
iex> MyCache.command!(["LRANGE", "mylist", "0", "-1"], key: "mylist")
213+
iex> Redix.command!(conn, ["LRANGE", "mylist", "0", "-1"])
272214
["hello", "world"]
273215

274-
iex> [
216+
iex> conn = MyCache.fetch_conn!(key: "mylist")
217+
iex> Redix.pipeline!(conn, [
275218
...> ["LPUSH", "mylist", "world"],
276219
...> ["LPUSH", "mylist", "hello"],
277220
...> ["LRANGE", "mylist", "0", "-1"]
278-
...> ]
279-
...> |> cache.pipeline!(key: "mylist")
221+
...> ])
280222
[1, 2, ["hello", "world"]]
281223
```
282224

@@ -287,8 +229,8 @@ you have to pass the cache name explicitly.
287229

288230
## Testing
289231

290-
To run the **NebulexRedisAdapter** tests you will have to have Redis running
291-
locally. **NebulexRedisAdapter** requires a complex setup for running tests
232+
To run the **Nebulex.Adapters.Redis** tests you will have to have Redis running
233+
locally. **Nebulex.Adapters.Redis** requires a complex setup for running tests
292234
(since it needs a few instances running, for standalone, cluster and Redis
293235
Cluster). For this reason, there is a [docker-compose.yml](docker-compose.yml)
294236
file in the repo so that you can use [Docker][docker] and
@@ -302,7 +244,7 @@ $ docker-compose up
302244
[docker]: https://www.docker.com/
303245
[docker_compose]: https://docs.docker.com/compose/
304246

305-
Since `NebulexRedisAdapter` uses the support modules and shared tests
247+
Since `Nebulex.Adapters.Redis` uses the support modules and shared tests
306248
from `Nebulex` and by default its test folder is not included in the Hex
307249
dependency, the following steps are required for running the tests.
308250

@@ -357,9 +299,9 @@ $ MIX_ENV=test mix run benchmarks/benchmark.exs
357299

358300
Contributions to Nebulex are very welcome and appreciated!
359301

360-
Use the [issue tracker](https://github.com/cabol/nebulex_redis_adapter/issues)
302+
Use the [issue tracker](https://github.com/elixir-nebulex/nebulex_redis_adapter/issues)
361303
for bug reports or feature requests. Open a
362-
[pull request](https://github.com/cabol/nebulex_redis_adapter/pulls)
304+
[pull request](https://github.com/elixir-nebulex/nebulex_redis_adapter/pulls)
363305
when you are ready to contribute.
364306

365307
When submitting a pull request you should not update the [CHANGELOG.md](CHANGELOG.md),
@@ -373,4 +315,4 @@ all checks run successfully.
373315

374316
Copyright (c) 2018, Carlos Bolaños.
375317

376-
NebulexRedisAdapter source code is licensed under the [MIT License](LICENSE).
318+
Nebulex.Adapters.Redis source code is licensed under the [MIT License](LICENSE).

0 commit comments

Comments
 (0)