:
This commit is contained in:
parent
8bd06a67ed
commit
8be51c0cf5
@ -20,7 +20,9 @@ defmodule Protohackers.PrimeTimeServer do
|
||||
mode: :binary,
|
||||
active: false,
|
||||
reuseaddr: true,
|
||||
exit_on_close: false
|
||||
exit_on_close: false,
|
||||
packet: :line,
|
||||
buffer: 1024 * 100
|
||||
]
|
||||
|
||||
case :gen_tcp.listen(port, listen_options) do
|
||||
@ -49,21 +51,43 @@ defmodule Protohackers.PrimeTimeServer do
|
||||
## Helpers
|
||||
|
||||
defp handle_connection(socket) do
|
||||
case recv_until_closed(socket, _buffer = "", _buffered_size = 0) do
|
||||
{:ok, data} -> :gen_tcp.send(socket, data)
|
||||
case parse_json(socket) do
|
||||
:ok -> :ok
|
||||
{:error, reason} -> Logger.error("Failed to receive data: #{inspect(reason)}")
|
||||
end
|
||||
|
||||
:gen_tcp.close(socket)
|
||||
end
|
||||
|
||||
@limit _100_kb = 1024 * 100
|
||||
defp recv_until_closed(socket, buffer, buffered_size) do
|
||||
defp parse_json(socket) do
|
||||
case :gen_tcp.recv(socket, 0, 10_000) do
|
||||
{:ok, data} when buffered_size + byte_size(data) > @limit -> {:error, :buffer_overflow}
|
||||
{:ok, data} -> recv_until_closed(socket, [buffer, data], buffered_size + byte_size(data))
|
||||
{:error, :closed} -> {:ok, buffer}
|
||||
{:error, reason} -> {:error, reason}
|
||||
{:ok, data} ->
|
||||
case Jason.decode(data) do
|
||||
{:ok, %{"method" => "isPrime", "number" => number}} when is_number(number) ->
|
||||
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
|
||||
|
||||
{: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
|
||||
|
1
mix.exs
1
mix.exs
@ -22,6 +22,7 @@ defmodule Protohackers.MixProject do
|
||||
# Run "mix help deps" to learn about dependencies.
|
||||
defp deps do
|
||||
[
|
||||
{:jason, "~> 1.4"}
|
||||
# {:dep_from_hexpm, "~> 0.3.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