forked from beam-telemetry/telemetry_metrics_statsd
-
Notifications
You must be signed in to change notification settings - Fork 1
/
udp.ex
60 lines (49 loc) · 1.62 KB
/
udp.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
defmodule TelemetryMetricsStatsd.UDP do
@moduledoc false
defstruct [:host, :port, :socket]
@opaque t :: %__MODULE__{
host: :inet.hostname() | :inet.ip_address() | :inet.local_address(),
port: :inet.port_number(),
socket: :gen_udp.socket()
}
@type config :: %{
:host => :inet.hostname() | :inet.ip_address() | :inet.local_address(),
optional(:port) => :inet.port_number(),
optional(:inet_address_family) => boolean()
}
@spec open(config()) ::
{:ok, t()} | {:error, reason :: term()}
def open(config) do
opts = [{:active, false}]
opts =
Enum.reduce(config, opts, fn
{:host, {:local, _}}, opts -> [:local | opts]
{:inet_address_family, value}, opts -> [value | opts]
{_key, _value}, opts -> opts
end)
case :gen_udp.open(0, opts) do
{:ok, socket} ->
udp = struct(__MODULE__, Map.put(config, :socket, socket))
{:ok, udp}
{:error, _} = err ->
err
end
end
@spec send(t(), iodata()) :: :ok | {:error, reason :: term()}
def send(%__MODULE__{host: host, port: port, socket: socket}, data) do
case host do
{:local, _} ->
:gen_udp.send(socket, host, 0, data)
_ ->
:gen_udp.send(socket, host, port, data)
end
end
@spec update(t(), :inet.hostname() | :inet.ip_address(), :inet.port_number()) :: t()
def update(%__MODULE__{} = udp, new_host, new_port) do
%__MODULE__{udp | host: new_host, port: new_port}
end
@spec close(t()) :: :ok
def close(%__MODULE__{socket: socket}) do
:gen_udp.close(socket)
end
end