Packages
thousand_island
1.3.1
1.5.0
1.4.3
1.4.2
1.4.1
1.4.0
1.3.14
1.3.13
1.3.12
1.3.11
1.3.10
1.3.9
1.3.8
1.3.7
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.0
1.0.0-pre.7
1.0.0-pre.6
1.0.0-pre.5
1.0.0-pre.4
1.0.0-pre.3
1.0.0-pre.2
1.0.0-pre.1
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
A simple & modern pure Elixir socket server
Current section
Files
Jump to
Current section
Files
lib/thousand_island/acceptor.ex
defmodule ThousandIsland.Acceptor do
@moduledoc false
use Task, restart: :transient
@spec start_link(
{server :: Supervisor.supervisor(), parent :: Supervisor.supervisor(),
ThousandIsland.ServerConfig.t()}
) :: {:ok, pid()}
def start_link(arg), do: Task.start_link(__MODULE__, :run, [arg])
@spec run(
{server :: Supervisor.supervisor(), parent :: Supervisor.supervisor(),
ThousandIsland.ServerConfig.t()}
) :: no_return
def run({server_pid, parent_pid, %ThousandIsland.ServerConfig{} = server_config}) do
listener_pid = ThousandIsland.Server.listener_pid(server_pid)
{listener_socket, listener_span} = ThousandIsland.Listener.acceptor_info(listener_pid)
connection_sup_pid = ThousandIsland.AcceptorSupervisor.connection_sup_pid(parent_pid)
acceptor_span = ThousandIsland.Telemetry.start_child_span(listener_span, :acceptor)
accept(listener_socket, connection_sup_pid, server_config, acceptor_span, 0)
end
defp accept(listener_socket, connection_sup_pid, server_config, span, count) do
with {:ok, socket} <- server_config.transport_module.accept(listener_socket),
:ok <- ThousandIsland.Connection.start(connection_sup_pid, socket, server_config, span) do
accept(listener_socket, connection_sup_pid, server_config, span, count + 1)
else
{:error, :too_many_connections} ->
ThousandIsland.Telemetry.span_event(span, :spawn_error)
accept(listener_socket, connection_sup_pid, server_config, span, count + 1)
{:error, :econnaborted} ->
ThousandIsland.Telemetry.span_event(span, :econnaborted)
accept(listener_socket, connection_sup_pid, server_config, span, count + 1)
{:error, reason} when reason in [:closed, :einval] ->
ThousandIsland.Telemetry.stop_span(span, %{connections: count})
{:error, reason} ->
ThousandIsland.Telemetry.stop_span(span, %{connections: count}, %{error: reason})
raise "Unexpected error in accept: #{inspect(reason)}"
end
end
end