changed
CHANGELOG.md
|
@@ -1,5 1,11 @@
|
1
1
|
# Changelog
|
2
2
|
|
3
|
## v1.4.0
|
4
|
|
5
|
### Bug fixes and improvements
|
6
|
|
7
|
* Introduce `Redix.PubSub.get_client/1`, which can be used to implement [client-side caching](https://redis.io/docs/manual/client-side-caching/).
|
8
|
|
3
9
|
## v1.3.0
|
4
10
|
|
5
11
|
### Bug fixes and improvements
|
changed
README.md
|
@@ -27,7 27,7 @@ This README refers to the main branch of Redix, not the latest released version
|
27
27
|
Add the `:redix` dependency to your `mix.exs` file. If you plan on connecting to a Redis server [over SSL][docs-ssl] you may want to add the optional [`:castore`][castore] dependency as well:
|
28
28
|
|
29
29
|
```elixir
|
30
|
- defp deps() do
|
30
|
defp deps do
|
31
31
|
[
|
32
32
|
{:redix, "~> 1.1"},
|
33
33
|
{:castore, ">= 0.0.0"}
|
changed
hex_metadata.config
|
@@ -2,7 2,7 @@
|
2
2
|
[{<<"GitHub">>,<<"https://github.com/whatyouhide/redix">>},
|
3
3
|
{<<"Sponsor">>,<<"https://github.com/sponsors/whatyouhide">>}]}.
|
4
4
|
{<<"name">>,<<"redix">>}.
|
5
|
- {<<"version">>,<<"1.3.0">>}.
|
5
|
{<<"version">>,<<"1.4.0">>}.
|
6
6
|
{<<"description">>,<<"Fast, pipelined, resilient Redis driver for Elixir.">>}.
|
7
7
|
{<<"elixir">>,<<"~> 1.11">>}.
|
8
8
|
{<<"app">>,<<"redix">>}.
|
|
@@ -24,12 24,12 @@
|
24
24
|
{<<"requirement">>,<<"~> 0.5.0 or ~> 1.0">>},
|
25
25
|
{<<"repository">>,<<"hexpm">>}]]}.
|
26
26
|
{<<"files">>,
|
27
|
- [<<"lib">>,<<"lib/redix.ex">>,<<"lib/redix">>,<<"lib/redix/exceptions.ex">>,
|
28
|
- <<"lib/redix/pubsub.ex">>,<<"lib/redix/format.ex">>,
|
29
|
- <<"lib/redix/start_options.ex">>,<<"lib/redix/pubsub">>,
|
30
|
- <<"lib/redix/pubsub/connection.ex">>,<<"lib/redix/protocol.ex">>,
|
31
|
- <<"lib/redix/telemetry.ex">>,<<"lib/redix/uri.ex">>,
|
32
|
- <<"lib/redix/connection.ex">>,<<"lib/redix/socket_owner.ex">>,
|
33
|
- <<"lib/redix/connector.ex">>,<<".formatter.exs">>,<<"mix.exs">>,
|
34
|
- <<"README.md">>,<<"LICENSE.txt">>,<<"CHANGELOG.md">>]}.
|
27
|
[<<"lib">>,<<"lib/redix">>,<<"lib/redix/start_options.ex">>,
|
28
|
<<"lib/redix/uri.ex">>,<<"lib/redix/protocol.ex">>,<<"lib/redix/pubsub">>,
|
29
|
<<"lib/redix/pubsub/connection.ex">>,<<"lib/redix/telemetry.ex">>,
|
30
|
<<"lib/redix/connection.ex">>,<<"lib/redix/pubsub.ex">>,
|
31
|
<<"lib/redix/connector.ex">>,<<"lib/redix/format.ex">>,
|
32
|
<<"lib/redix/exceptions.ex">>,<<"lib/redix/socket_owner.ex">>,
|
33
|
<<"lib/redix.ex">>,<<".formatter.exs">>,<<"mix.exs">>,<<"README.md">>,
|
34
|
<<"LICENSE.txt">>,<<"CHANGELOG.md">>]}.
|
35
35
|
{<<"build_tools">>,[<<"mix">>]}.
|
changed
lib/redix/connection.ex
|
@@ -124,7 124,7 @@ defmodule Redix.Connection do
|
124
124
|
## Init callbacks
|
125
125
|
|
126
126
|
@impl true
|
127
|
- def callback_mode(), do: :state_functions
|
127
|
def callback_mode, do: :state_functions
|
128
128
|
|
129
129
|
@impl true
|
130
130
|
def init(opts) do
|
changed
lib/redix/connector.ex
|
@@ -250,7 250,13 @@ defmodule Redix.Connector do
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
|
- defp sync_command(transport, socket, command, timeout) do
|
253
|
@spec sync_command(
|
254
|
:ssl | :gen_tcp,
|
255
|
:gen_tcp.socket() | :ssl.sslsocket(),
|
256
|
[String.t()],
|
257
|
integer()
|
258
|
) :: {:ok, any} | {:error, any}
|
259
|
def sync_command(transport, socket, command, timeout) do
|
254
260
|
with :ok <- transport.send(socket, Redix.Protocol.pack(command)),
|
255
261
|
do: recv_response(transport, socket, &Redix.Protocol.parse/1, timeout)
|
256
262
|
end
|
changed
lib/redix/pubsub.ex
|
@@ -416,4 416,26 @@ defmodule Redix.PubSub do
|
416
416
|
when is_binary(patterns) or is_list(patterns) do
|
417
417
|
:gen_statem.call(conn, {:punsubscribe, List.wrap(patterns), subscriber})
|
418
418
|
end
|
419
|
|
420
|
@doc """
|
421
|
Gets the Redis `CLIENT ID` associated with a connection.
|
422
|
|
423
|
This is useful for implementing [**client-side
|
424
|
caching**](https://redis.io/docs/manual/client-side-caching/), where you can
|
425
|
subscribe your pub/sub connection to changes on keys.
|
426
|
|
427
|
If the pub/sub connection is currently disconnected, this function returns
|
428
|
`{:error, error}`.
|
429
|
|
430
|
## Examples
|
431
|
|
432
|
iex> Redix.PubSub.get_client_id(conn)
|
433
|
{:ok, 123}
|
434
|
|
435
|
"""
|
436
|
@doc since: "1.4.0"
|
437
|
@spec get_client_id(connection()) :: {:ok, integer()} | {:error, Redix.ConnectionError.t()}
|
438
|
def get_client_id(conn) do
|
439
|
:gen_statem.call(conn, :get_client_id)
|
440
|
end
|
419
441
|
end
|
changed
lib/redix/pubsub/connection.ex
|
@@ -13,6 13,7 @@ defmodule Redix.PubSub.Connection do
|
13
13
|
:backoff_current,
|
14
14
|
:last_disconnect_reason,
|
15
15
|
:connected_address,
|
16
|
:client_id,
|
16
17
|
subscriptions: %{},
|
17
18
|
monitors: %{}
|
18
19
|
]
|
|
@@ -20,7 21,7 @@ defmodule Redix.PubSub.Connection do
|
20
21
|
@backoff_exponent 1.5
|
21
22
|
|
22
23
|
@impl true
|
23
|
- def callback_mode(), do: :state_functions
|
24
|
def callback_mode, do: :state_functions
|
24
25
|
|
25
26
|
@impl true
|
26
27
|
def init(opts) do
|
|
@@ -28,14 29,14 @@ defmodule Redix.PubSub.Connection do
|
28
29
|
data = %__MODULE__{opts: opts, transport: transport}
|
29
30
|
|
30
31
|
if opts[:sync_connect] do
|
31
|
- with {:ok, socket, address} <- Connector.connect(data.opts, _conn_pid = self()),
|
32
|
- :ok <- setopts(data, socket, active: :once) do
|
32
|
with {:ok, socket, address, client_id} <- connect(data) do
|
33
33
|
data = %__MODULE__{
|
34
34
|
data
|
35
35
|
| socket: socket,
|
36
36
|
last_disconnect_reason: nil,
|
37
37
|
backoff_current: nil,
|
38
|
- connected_address: address
|
38
|
connected_address: address,
|
39
|
client_id: client_id
|
39
40
|
}
|
40
41
|
|
41
42
|
{:ok, :connected, data}
|
|
@@ -104,8 105,7 @@ defmodule Redix.PubSub.Connection do
|
104
105
|
end
|
105
106
|
|
106
107
|
def disconnected(:internal, :connect, data) do
|
107
|
- with {:ok, socket, address} <- Connector.connect(data.opts, _conn_pid = self()),
|
108
|
- :ok <- setopts(data, socket, active: :once) do
|
108
|
with {:ok, socket, address, client_id} <- connect(data) do
|
109
109
|
:telemetry.execute([:redix, :connection], %{}, %{
|
110
110
|
connection: self(),
|
111
111
|
connection_name: data.opts[:name],
|
|
@@ -118,7 118,8 @@ defmodule Redix.PubSub.Connection do
|
118
118
|
| socket: socket,
|
119
119
|
last_disconnect_reason: nil,
|
120
120
|
backoff_current: nil,
|
121
|
- connected_address: address
|
121
|
connected_address: address,
|
122
|
client_id: client_id
|
122
123
|
}
|
123
124
|
|
124
125
|
{:next_state, :connected, data, {:next_event, :internal, :handle_connection}}
|
|
@@ -193,6 194,11 @@ defmodule Redix.PubSub.Connection do
|
193
194
|
{:keep_state, data}
|
194
195
|
end
|
195
196
|
|
197
|
def disconnected({:call, from}, :get_client_id, _data) do
|
198
|
reply = {:error, %ConnectionError{reason: :closed}}
|
199
|
{:keep_state_and_data, {:reply, from, reply}}
|
200
|
end
|
201
|
|
196
202
|
def connected(:internal, :handle_connection, data) do
|
197
203
|
if map_size(data.subscriptions) > 0 do
|
198
204
|
case resubscribe_after_reconnection(data) do
|
|
@@ -224,6 230,10 @@ defmodule Redix.PubSub.Connection do
|
224
230
|
end
|
225
231
|
end
|
226
232
|
|
233
|
def connected({:call, from}, :get_client_id, data) do
|
234
|
{:keep_state_and_data, {:reply, from, {:ok, data.client_id}}}
|
235
|
end
|
236
|
|
227
237
|
def connected(:info, {transport_closed, socket}, %__MODULE__{socket: socket} = data)
|
228
238
|
when transport_closed in [:tcp_closed, :ssl_closed] do
|
229
239
|
disconnect(data, transport_closed, _handle_disconnection? = true)
|
|
@@ -561,6 571,16 @@ defmodule Redix.PubSub.Connection do
|
561
571
|
defp key_for_target(:psubscribe, pattern), do: {:pattern, pattern}
|
562
572
|
defp key_for_target(:punsubscribe, pattern), do: {:pattern, pattern}
|
563
573
|
|
574
|
defp connect(%__MODULE__{opts: opts, transport: transport} = data) do
|
575
|
timeout = Keyword.fetch!(opts, :timeout)
|
576
|
|
577
|
with {:ok, socket, address} <- Connector.connect(opts, _conn_pid = self()),
|
578
|
{:ok, client_id} <- Connector.sync_command(transport, socket, ["CLIENT", "ID"], timeout),
|
579
|
:ok <- setopts(data, socket, active: :once) do
|
580
|
{:ok, socket, address, client_id}
|
581
|
end
|
582
|
end
|
583
|
|
564
584
|
defp setopts(data, socket, opts) do
|
565
585
|
inets_mod(data.transport).setopts(socket, opts)
|
566
586
|
end
|
changed
lib/redix/telemetry.ex
|
@@ -123,7 123,7 @@ defmodule Redix.Telemetry do
|
123
123
|
|
124
124
|
"""
|
125
125
|
@spec attach_default_handler() :: :ok | {:error, :already_exists}
|
126
|
- def attach_default_handler() do
|
126
|
def attach_default_handler do
|
127
127
|
events = [
|
128
128
|
[:redix, :disconnection],
|
129
129
|
[:redix, :connection],
|
changed
mix.exs
|
@@ -5,9 5,9 @@ defmodule Redix.Mixfile do
|
5
5
|
|
6
6
|
@repo_url "https://github.com/whatyouhide/redix"
|
7
7
|
|
8
|
- @version "1.3.0"
|
8
|
@version "1.4.0"
|
9
9
|
|
10
|
- def project() do
|
10
|
def project do
|
11
11
|
[
|
12
12
|
app: :redix,
|
13
13
|
version: @version,
|
|
@@ -47,11 47,11 @@ defmodule Redix.Mixfile do
|
47
47
|
]
|
48
48
|
end
|
49
49
|
|
50
|
- def application() do
|
50
|
def application do
|
51
51
|
[extra_applications: [:logger, :ssl]]
|
52
52
|
end
|
53
53
|
|
54
|
- defp package() do
|
54
|
defp package do
|
55
55
|
[
|
56
56
|
maintainers: ["Andrea Leopardi"],
|
57
57
|
licenses: ["MIT"],
|
|
@@ -59,22 59,18 @@ defmodule Redix.Mixfile do
|
59
59
|
]
|
60
60
|
end
|
61
61
|
|
62
|
- defp deps() do
|
62
|
defp deps do
|
63
63
|
[
|
64
64
|
{:telemetry, "~> 0.4.0 or ~> 1.0"},
|
65
65
|
{:castore, "~> 0.1.0 or ~> 1.0", optional: true},
|
66
66
|
{:nimble_options, "~> 0.5.0 or ~> 1.0"},
|
67
67
|
|
68
68
|
# Dev and test dependencies
|
69
|
{:dialyxir, "~> 1.4 and >= 1.4.2", only: [:dev, :test], runtime: false},
|
69
70
|
{:ex_doc, "~> 0.28", only: :dev},
|
70
71
|
{:excoveralls, "~> 0.17", only: :test},
|
71
72
|
{:propcheck, "~> 1.1", only: :test},
|
72
73
|
{:stream_data, "~> 0.4", only: [:dev, :test]}
|
73
|
- ]
|
74
|
- if Version.match?(System.version(), "~> 1.12") do
|
75
|
- [{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false}]
|
76
|
- else
|
77
|
- []
|
78
|
- end
|
74
|
]
|
79
75
|
end
|
80
76
|
end
|