:
This commit is contained in:
parent
8bd06a67ed
commit
8be51c0cf5
@ -20,7 +20,9 @@ defmodule Protohackers.PrimeTimeServer do
|
|||||||
mode: :binary,
|
mode: :binary,
|
||||||
active: false,
|
active: false,
|
||||||
reuseaddr: true,
|
reuseaddr: true,
|
||||||
exit_on_close: false
|
exit_on_close: false,
|
||||||
|
packet: :line,
|
||||||
|
buffer: 1024 * 100
|
||||||
]
|
]
|
||||||
|
|
||||||
case :gen_tcp.listen(port, listen_options) do
|
case :gen_tcp.listen(port, listen_options) do
|
||||||
@ -49,21 +51,43 @@ defmodule Protohackers.PrimeTimeServer do
|
|||||||
## Helpers
|
## Helpers
|
||||||
|
|
||||||
defp handle_connection(socket) do
|
defp handle_connection(socket) do
|
||||||
case recv_until_closed(socket, _buffer = "", _buffered_size = 0) do
|
case parse_json(socket) do
|
||||||
{:ok, data} -> :gen_tcp.send(socket, data)
|
:ok -> :ok
|
||||||
{:error, reason} -> Logger.error("Failed to receive data: #{inspect(reason)}")
|
{:error, reason} -> Logger.error("Failed to receive data: #{inspect(reason)}")
|
||||||
end
|
end
|
||||||
|
|
||||||
:gen_tcp.close(socket)
|
:gen_tcp.close(socket)
|
||||||
end
|
end
|
||||||
|
|
||||||
@limit _100_kb = 1024 * 100
|
defp parse_json(socket) do
|
||||||
defp recv_until_closed(socket, buffer, buffered_size) do
|
|
||||||
case :gen_tcp.recv(socket, 0, 10_000) do
|
case :gen_tcp.recv(socket, 0, 10_000) do
|
||||||
{:ok, data} when buffered_size + byte_size(data) > @limit -> {:error, :buffer_overflow}
|
{:ok, data} ->
|
||||||
{:ok, data} -> recv_until_closed(socket, [buffer, data], buffered_size + byte_size(data))
|
case Jason.decode(data) do
|
||||||
{:error, :closed} -> {:ok, buffer}
|
{:ok, %{"method" => "isPrime", "number" => number}} when is_number(number) ->
|
||||||
{:error, reason} -> {:error, reason}
|
Logger.debug("Received valid request for number: #{number}")
|
||||||
|
response = %{"method" => "isPrime", "prime" => prime?(number)}
|
||||||
|
:gen_tcp.send(socket, [Jason.encode!(response), ?\n])
|
||||||
|
parse_json(socket)
|
||||||
|
|
||||||
|
other ->
|
||||||
|
Logger.debug("Received invalid request: #{inspect(other)}")
|
||||||
|
:gen_tcp.send(socket, "malformed request\n")
|
||||||
|
{:error, :invalid_request}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
{:error, :closed} ->
|
||||||
|
:ok
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
{:error, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp prime?(number) when is_float(number), do: false
|
||||||
|
defp prime?(number) when number <= 1, do: false
|
||||||
|
defp prime?(number) when number in [2, 3], do: true
|
||||||
|
|
||||||
|
defp prime?(number) do
|
||||||
|
not Enum.any?(2..trunc(:math.sqrt(number)), &(rem(number, &1) == 0))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
1
mix.exs
1
mix.exs
@ -22,6 +22,7 @@ defmodule Protohackers.MixProject do
|
|||||||
# Run "mix help deps" to learn about dependencies.
|
# Run "mix help deps" to learn about dependencies.
|
||||||
defp deps do
|
defp deps do
|
||||||
[
|
[
|
||||||
|
{:jason, "~> 1.4"}
|
||||||
# {:dep_from_hexpm, "~> 0.3.0"},
|
# {:dep_from_hexpm, "~> 0.3.0"},
|
||||||
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
||||||
]
|
]
|
||||||
|
3
mix.lock
Normal file
3
mix.lock
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
%{
|
||||||
|
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user