Current section
Files
Jump to
Current section
Files
src/aqlc_tcp.erl
-module(aqlc_tcp).
-behaviour(gen_server).
%% API
-export([start_link/2, start_link/3, stop/1, send/2]).
%% gen_server callbacks.
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-include("aqlc.hrl").
-record(state, {socket}).
-spec start_link(address(), port_number()) -> {ok, pid()} | {error, term()}.
start_link(Address, Port) ->
start_link(Address, Port, []).
-spec start_link(address(), port_number(), [connect_option()]) -> {ok, pid()} | {error, term()}.
start_link(Address, Port, Options) ->
gen_server:start_link(?MODULE, {Address, Port, Options}, []).
-spec stop(pid()) -> ok.
stop(Pid) ->
gen_server:call(Pid, stop).
-spec send(pid(), iodata()) -> {ok, binary()} | {error, term()}.
send(Pid, Data) ->
gen_server:call(Pid, {send, Data}).
init({Address, Port, Options}) ->
Timeout = proplists:get_value(timeout, Options, ?DEFAULT_CONNECT_TIMEOUT),
case gen_tcp:connect(Address, Port, [binary, {active, false}], Timeout) of
{ok, Socket} ->
{ok, #state{socket = Socket}};
{error, Reason} ->
{stop, Reason}
end.
handle_call({send, Data}, _From, State = #state{socket = Socket}) ->
case gen_tcp:send(Socket, Data) of
ok ->
Response = gen_tcp:recv(Socket, 0, ?DEFAULT_RECEIVE_TIMEOUT),
{reply, Response, State};
Error = {error, _Reason} ->
{reply, Error, State}
end;
handle_call(stop, _From, State = #state{socket = Socket}) ->
ok = gen_tcp:close(Socket),
{stop, normal, ok, State};
handle_call(_Request, _From, State) ->
{reply, ok, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.