Skip to content

Commit

Permalink
feat: change Protocol.Server.cancel_message/2 function a macro (#495)
Browse files Browse the repository at this point in the history
This allows us to use this piece of code in function head in pattern
match. This reduces places where the magic value is required and make
the code a little bit neater and cleaner.
  • Loading branch information
hauleth authored Nov 25, 2024
1 parent 15802b7 commit 9453cf8
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 23 deletions.
6 changes: 3 additions & 3 deletions lib/supavisor/client_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ defmodule Supavisor.ClientHandler do
@behaviour :ranch_protocol
@behaviour :gen_statem
@proto [:tcp, :ssl]
@cancel_query_msg <<16::32, 1234::16, 5678::16>>
@switch_active_count Application.compile_env(:supavisor, :switch_active_count)
@subscribe_retries Application.compile_env(:supavisor, :subscribe_retries)
@timeout_subscribe 500
Expand All @@ -22,10 +21,11 @@ defmodule Supavisor.ClientHandler do
Helpers,
Monitoring.Telem,
Protocol.Client,
Protocol.Server,
Tenants
}

require Supavisor.Protocol.Server, as: Server

@impl true
def start_link(ref, transport, opts) do
pid = :proc_lib.spawn_link(__MODULE__, :init, [ref, transport, opts])
Expand Down Expand Up @@ -111,7 +111,7 @@ defmodule Supavisor.ClientHandler do
end

# cancel request
def handle_event(:info, {_, _, <<@cancel_query_msg, pid::32, key::32>>}, _, _) do
def handle_event(:info, {_, _, Server.cancel_message(pid, key)}, _, _) do
Logger.debug("ClientHandler: Got cancel query for #{inspect({pid, key})}")
:ok = HandlerHelpers.send_cancel_query(pid, key)
{:stop, {:shutdown, :cancel_query}}
Expand Down
3 changes: 2 additions & 1 deletion lib/supavisor/handler_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ defmodule Supavisor.HandlerHelpers do
@moduledoc false

alias Phoenix.PubSub
alias Supavisor.Protocol.Server

require Supavisor.Protocol.Server, as: Server

@spec sock_send(Supavisor.sock(), iodata()) :: :ok | {:error, term()}
def sock_send({mod, sock}, data) do
Expand Down
11 changes: 6 additions & 5 deletions lib/supavisor/protocol/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ defmodule Supavisor.Protocol.Server do
}
end

defmacro cancel_message(pid, key) do
quote do
<<unquote(@msg_cancel_header)::binary, unquote(pid)::32, unquote(key)::32>>
end
end

@spec decode(iodata()) :: [Pkt.t()] | []
def decode(data) do
decode(data, [])
Expand Down Expand Up @@ -456,11 +462,6 @@ defmodule Supavisor.Protocol.Server do
<<byte_size(bin) + 9::32, 0, 3, 0, 0, bin::binary, 0>>
end

@spec cancel_message(non_neg_integer, non_neg_integer) :: iodata
def cancel_message(pid, key) do
[@msg_cancel_header, <<pid::32, key::32>>]
end

@spec has_read_only_error?(list) :: boolean
def has_read_only_error?(pkts) do
Enum.any?(pkts, fn
Expand Down
31 changes: 17 additions & 14 deletions test/supavisor/protocol_test.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
defmodule Supavisor.ProtocolTest do
use ExUnit.Case, async: true
alias Supavisor.Protocol.Server, as: S

@subject Supavisor.Protocol.Server

require Supavisor.Protocol.Server

@initial_data %{
"DateStyle" => "ISO, MDY",
Expand All @@ -27,42 +30,43 @@ defmodule Supavisor.ProtocolTest do
97, 105, 108, 101, 100, 0, 0>>

test "encode_parameter_status/1" do
result = S.encode_parameter_status(@initial_data)
result = @subject.encode_parameter_status(@initial_data)

for {key, value} <- @initial_data do
assert :erlang.is_binary(key)
assert :erlang.is_binary(value)
encoded = S.encode_pkt(:parameter_status, key, value)
assert Enum.member?(result, encoded)
for entry <- @initial_data do
assert {key, value} = entry
assert is_binary(key)
assert is_binary(value)
encoded = @subject.encode_pkt(:parameter_status, key, value)
assert encoded in result
end
end

test "encode_pkt/3" do
key = "TimeZone"
value = "UTC"
result = S.encode_pkt(:parameter_status, key, value)
result = @subject.encode_pkt(:parameter_status, key, value)

assert result == [<<?S, 17::32>>, [key, <<0>>, value, <<0>>]]
end

test "backend_key_data/0" do
{header, payload} = S.backend_key_data()
{header, payload} = @subject.backend_key_data()
len = byte_size(payload) + 4

assert [
%S.Pkt{
%@subject.Pkt{
tag: :backend_key_data,
len: 13,
payload: %{pid: _, key: _}
}
] = S.decode([header, payload] |> IO.iodata_to_binary())
] = @subject.decode([header, payload] |> IO.iodata_to_binary())

assert header == <<?K, len::32>>
assert byte_size(payload) == 8
end

test "decode_payload for error_response" do
assert S.decode(@auth_bin_error) == [
assert @subject.decode(@auth_bin_error) == [
%Supavisor.Protocol.Server.Pkt{
tag: :error_response,
len: 112,
Expand All @@ -84,7 +88,6 @@ defmodule Supavisor.ProtocolTest do
key = 123_456
expected = <<0, 0, 0, 16, 4, 210, 22, 46, 0, 0, 0, 123, 0, 1, 226, 64>>

assert S.cancel_message(pid, key)
|> IO.iodata_to_binary() == expected
assert @subject.cancel_message(pid, key) == expected
end
end

0 comments on commit 9453cf8

Please sign in to comment.