Packages
xandra
0.18.0-rc.1
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.18.0-rc.9
0.18.0-rc.8
0.18.0-rc.7
0.18.0-rc.6
0.18.0-rc.5
0.18.0-rc.4
0.18.0-rc.3
0.18.0-rc.2
0.18.0-rc.1
0.17.0
0.16.0
0.15.0
0.15.0-rc.1
0.14.0
0.13.1
0.13.0
0.12.0
0.11.0
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.0
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
Fast, simple, and robust Cassandra driver for Elixir.
Current section
Files
Jump to
Current section
Files
lib/xandra/transport.ex
defmodule Xandra.Transport do
@moduledoc false
# Internal module to abstract away operations on transport sockets, independent from
# the transport (TCP or SSL).
@type options() :: [{atom(), term()} | atom()]
@type error_reason() :: :inet.posix() | term()
@type t() :: %__MODULE__{
module: :gen_tcp | :ssl,
options: options(),
socket: :gen_tcp.socket() | :ssl.sslsocket() | nil
}
@enforce_keys [:module, :options]
defstruct [:module, :options, :socket]
defguard is_data_message(transport, msg)
when is_tuple(msg) and tuple_size(msg) == 3 and elem(msg, 0) in [:tcp, :ssl] and
elem(msg, 1) == transport.socket
defguard is_closed_message(transport, msg)
when is_tuple(msg) and tuple_size(msg) == 2 and
elem(msg, 0) in [:tcp_closed, :ssl_closed] and
elem(msg, 1) == transport.socket
defguard is_error_message(transport, msg)
when is_tuple(msg) and tuple_size(msg) == 3 and
elem(msg, 0) in [:tcp_error, :ssl_error] and
elem(msg, 1) == transport.socket
@spec connect(t(), :inet.ip_address() | charlist(), :inet.port_number(), timeout()) ::
{:ok, t()} | {:error, error_reason()}
def connect(%__MODULE__{socket: nil} = transport, address, port, timeout) do
with {:ok, socket} <- transport.module.connect(address, port, transport.options, timeout) do
{:ok, %__MODULE__{transport | socket: socket}}
end
end
@spec send(t(), iodata()) :: :ok | {:error, error_reason()}
def send(%__MODULE__{socket: socket, module: module}, data) when not is_nil(socket) do
module.send(socket, data)
end
@spec recv(t(), integer(), timeout()) :: {:ok, binary()} | {:error, error_reason()}
def recv(%__MODULE__{socket: socket, module: module}, bytes, timeout)
when not is_nil(socket) and is_integer(bytes) do
module.recv(socket, bytes, timeout)
end
@spec setopts(t(), options()) :: :ok | {:error, error_reason}
def setopts(%__MODULE__{} = transport, options) when is_list(options) do
inet_mod(transport.module).setopts(transport.socket, options)
end
@spec address_and_port(t()) ::
{:ok, {:inet.ip_address(), :inet.port_number()}} | {:error, error_reason}
def address_and_port(%__MODULE__{socket: socket} = transport) when not is_nil(socket) do
inet_mod(transport.module).peername(socket)
end
@spec close(t()) :: t()
def close(%__MODULE__{} = transport) do
_ = transport.module.close(transport.socket)
%__MODULE__{transport | socket: nil}
end
defp inet_mod(:gen_tcp), do: :inet
defp inet_mod(:ssl), do: :ssl
end