changed CHANGELOG.md
 
@@ -1,10 1,17 @@
1
1
# Changelog
2
2
3
## v1.4.2
4
5
### Bug fixes and improvements
6
7
* Speed up `Redix.Protocol` a little bit for common responses (`"OK"` and friends).
8
* Fix a bug where `:tcp_closed`/`:ssl_closed` and `:tcp_error`/`:ssl_error` messages wouldn't arrive to the socket owner, and Redix would get stuck in a disconnected state when sending would error out. See the discussion in [#265](https://github.com/whatyouhide/redix/issues/265).
9
3
10
## v1.4.1
4
11
5
12
### Bug fixes and improvements
6
13
7
- * `Redix.PubSub.get_client/1` is not available only behind the `:fetch_client_id_on_connect` option that you can pass to `Redix.PubSub.start_link/1`. This option defaults to `false`, so that this version of Redix is compatible with Redis v4 or earlier out of the box. To opt in into the behavior desired for [client-side caching](https://redis.io/docs/manual/client-side-caching/) and use `Redix.PubSub.get_client/1`, pass `fetch_client_id_on_connect: true` to `Redix.PubSub.start_link/1`.
14
* `Redix.PubSub.get_client_id/1` is not available only behind the `:fetch_client_id_on_connect` option that you can pass to `Redix.PubSub.start_link/1`. This option defaults to `false`, so that this version of Redix is compatible with Redis v4 or earlier out of the box. To opt in into the behavior desired for [client-side caching](https://redis.io/docs/manual/client-side-caching/) and use `Redix.PubSub.get_client_id/1`, pass `fetch_client_id_on_connect: true` to `Redix.PubSub.start_link/1`.
8
15
9
16
## v1.4.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.4.1">>}.
5
{<<"version">>,<<"1.4.2">>}.
6
6
{<<"description">>,<<"Fast, pipelined, resilient Redis driver for Elixir.">>}.
7
7
{<<"elixir">>,<<"~> 1.11">>}.
8
8
{<<"app">>,<<"redix">>}.
 
@@ -25,11 25,11 @@
25
25
{<<"repository">>,<<"hexpm">>}]]}.
26
26
{<<"files">>,
27
27
[<<"lib">>,<<"lib/redix">>,<<"lib/redix/protocol.ex">>,
28
- <<"lib/redix/telemetry.ex">>,<<"lib/redix/socket_owner.ex">>,
29
- <<"lib/redix/format.ex">>,<<"lib/redix/start_options.ex">>,
28
<<"lib/redix/connection.ex">>,<<"lib/redix/format.ex">>,
29
<<"lib/redix/exceptions.ex">>,<<"lib/redix/telemetry.ex">>,
30
<<"lib/redix/socket_owner.ex">>,<<"lib/redix/uri.ex">>,
31
<<"lib/redix/connector.ex">>,<<"lib/redix/start_options.ex">>,
30
32
<<"lib/redix/pubsub">>,<<"lib/redix/pubsub/connection.ex">>,
31
- <<"lib/redix/connection.ex">>,<<"lib/redix/uri.ex">>,
32
- <<"lib/redix/exceptions.ex">>,<<"lib/redix/pubsub.ex">>,
33
- <<"lib/redix/connector.ex">>,<<"lib/redix.ex">>,<<".formatter.exs">>,
33
<<"lib/redix/pubsub.ex">>,<<"lib/redix.ex">>,<<".formatter.exs">>,
34
34
<<"mix.exs">>,<<"README.md">>,<<"LICENSE.txt">>,<<"CHANGELOG.md">>]}.
35
35
{<<"build_tools">>,[<<"mix">>]}.
changed lib/redix/connection.ex
 
@@ -271,9 271,13 @@ defmodule Redix.Connection do
271
271
{:keep_state, data, actions}
272
272
273
273
{:error, _reason} ->
274
- # The socket owner will get a closed message at some point, so we just move to the
275
- # disconnected state.
274
# The socket owner is not guaranteed to get a "closed" message, even if we close the
275
# socket here. So, we move to the disconnected state but also notify the owner that
276
# sending failed. If the owner already got the "closed" message, it exited so this
277
# message goes nowere, otherwise the socket owner will exit and notify the connection.
278
# See https://github.com/whatyouhide/redix/issues/265.
276
279
:ok = data.transport.close(data.socket)
280
send(data.socket_owner, {:send_errored, self()})
277
281
{:next_state, :disconnected, data}
278
282
end
279
283
else
changed lib/redix/protocol.ex
 
@@ -25,6 25,7 @@ defmodule Redix.Protocol do
25
25
26
26
@crlf "\r\n"
27
27
@crlf_iodata [?\r, ?\n]
28
@max_integer_digits 18
28
29
29
30
@doc ~S"""
30
31
Packs a list of Elixir terms to a Redis (RESP) array.
 
@@ -80,6 81,9 @@ defmodule Redix.Protocol do
80
81
@spec parse(binary) :: on_parse(redis_value)
81
82
def parse(data)
82
83
84
# Clause for the most common response.
85
def parse(" OK\r\n" <> rest), do: {:ok, "OK", rest}
86
83
87
def parse(" " <> rest), do: parse_simple_string(rest)
84
88
def parse("-" <> rest), do: parse_error(rest)
85
89
def parse(":" <> rest), do: parse_integer(rest)
 
@@ -135,12 139,25 @@ defmodule Redix.Protocol do
135
139
|> resolve_cont(&{:ok, %Redix.Error{message: &1}, &2})
136
140
end
137
141
138
- defp parse_integer(""), do: {:continuation, &parse_integer/1}
142
# Fast integer clauses for non-split packets.
143
for n <- 1..@max_integer_digits do
144
defp parse_integer(<<digits::binary-size(unquote(n)), "\r\n", rest::binary>> = binary) do
145
String.to_integer(digits)
146
rescue
147
ArgumentError -> parse_integer_with_splits(binary)
148
else
149
int -> {:ok, int, rest}
150
end
151
end
139
152
140
- defp parse_integer("-" <> rest),
153
defp parse_integer(bin), do: parse_integer_with_splits(bin)
154
155
defp parse_integer_with_splits(""), do: {:continuation, &parse_integer_with_splits/1}
156
157
defp parse_integer_with_splits("-" <> rest),
141
158
do: resolve_cont(parse_integer_without_sign(rest), &{:ok, -&1, &2})
142
159
143
- defp parse_integer(bin), do: parse_integer_without_sign(bin)
160
defp parse_integer_with_splits(bin), do: parse_integer_without_sign(bin)
144
161
145
162
defp parse_integer_without_sign("") do
146
163
{:continuation, &parse_integer_without_sign/1}
changed lib/redix/socket_owner.ex
 
@@ -50,6 50,19 @@ defmodule Redix.SocketOwner do
50
50
end
51
51
end
52
52
53
# The connection is notifying the socket owner that sending failed. If the socket owner
54
# gets this, it can stop normally without waiting for the "closed"/"error" network
55
# message from the socket.
56
def handle_info({:send_errored, conn}, %__MODULE__{conn: conn} = state) do
57
error =
58
case state.transport do
59
:ssl -> {:ssl_error, :closed}
60
:gen_tcp -> {:tcp_error, :closed}
61
end
62
63
stop(error, state)
64
end
65
53
66
def handle_info({transport, socket, data}, %__MODULE__{socket: socket} = state)
54
67
when transport in [:tcp, :ssl] do
55
68
:ok = setopts(state, socket, active: :once)
changed lib/redix/start_options.ex
 
@@ -236,7 236,9 @@ defmodule Redix.StartOptions do
236
236
]
237
237
]
238
238
239
- @redix_start_link_opts_schema start_link_opts_schema |> Keyword.drop([:fetch_client_id_on_connect]) |> NimbleOptions.new!()
239
@redix_start_link_opts_schema start_link_opts_schema
240
|> Keyword.drop([:fetch_client_id_on_connect])
241
|> NimbleOptions.new!()
240
242
@redix_pubsub_start_link_opts_schema NimbleOptions.new!(start_link_opts_schema)
241
243
242
244
@spec options_docs(:redix | :redix_pubsub) :: String.t()
changed mix.exs
 
@@ -5,7 5,7 @@ defmodule Redix.Mixfile do
5
5
6
6
@repo_url "https://github.com/whatyouhide/redix"
7
7
8
- @version "1.4.1"
8
@version "1.4.2"
9
9
10
10
def project do
11
11
[