Skip to content

Instantly share code, notes, and snippets.

@joewilliams
Created January 21, 2009 04:20
Show Gist options
  • Save joewilliams/49851 to your computer and use it in GitHub Desktop.
Save joewilliams/49851 to your computer and use it in GitHub Desktop.
<snip>
set(Key, Value) ->
Flag = random:uniform(65000),
set(Key, Flag, "0", Value).
set(Key, Flag, ExpTime, Value) when is_integer(Flag) ->
set(Key, integer_to_list(Flag), ExpTime, Value);
set(Key, Flag, ExpTime, Value) when is_integer(ExpTime) ->
set(Key, Flag, integer_to_list(ExpTime), Value);
set(Key, Flag, ExpTime, Value) when is_integer(Value) ->
set(Key, Flag, ExpTime, integer_to_list(Value));
set(Key, Flag, ExpTime, Value) when is_atom(Value) ->
set(Key, Flag, ExpTime, atom_to_list(Value));
set(Key, Flag, ExpTime, Value) ->
case gen_server:call(?SERVER, {set, {Key, Flag, ExpTime, Value}}) of
["STORED"] -> ok;
[X] -> X
end.
<snip>
%% @doc Increment already existing value.
increment(Key, Value) when is_integer(Value) ->
increment(Key, integer_to_list(Value));
increment(Key, Value) ->
gen_server:call(?SERVER, {increment, {Key, Value}}).
%% @doc Decrement already existing value.
decrement(Key, Value) when is_integer(Value) ->
decrement(Key, integer_to_list(Value));
decrement(Key, Value) ->
gen_server:call(?SERVER, {decrement, {Key, Value}}).
<snip>
handle_call({set, {Key, Flag, ExpTime, Value}}, _From, Socket) ->
Bytes = length(Value),
BytesStr = integer_to_list(Bytes),
Reply = send_storage_cmd(
Socket,
iolist_to_binary([
<<"set ">>, Key, <<" ">>, Flag, <<" ">>, ExpTime, <<" ">>, BytesStr
]),
Value
),
{reply, Reply, Socket};
<snip>
handle_call({increment, {Key, Value}}, _From, Socket) ->
Reply = send_incr_decr_cmd(
Socket,
"incr " ++ " " ++ Key ++ " " ++ Value),
{reply, Reply, Socket};
handle_call({decrement, {Key, Value}}, _From, Socket) ->
Reply = send_incr_decr_cmd(
Socket,
"decr " ++ " " ++ Key ++ " " ++ Value),
{reply, Reply, Socket}.
<snip>
%% @private
%% @doc send_generic_cmd/2 function for simple informational and deletion commands
send_generic_cmd(Socket, Cmd) ->
gen_tcp:send(Socket, <<Cmd/binary, "\r\n">>),
Reply = recv_simple_reply(),
Reply.
%% @private
%% @doc send_storage_cmd/3 funtion for storage commands
send_storage_cmd(Socket, Cmd, Value) ->
gen_tcp:send(Socket, <<Cmd/binary, "\r\n">>),
gen_tcp:send(Socket, Value ++ "\r\n"),
Reply = recv_simple_reply(),
Reply.
<snip>
%% @private
%% @doc send_incr_decr_cmd/2 function for simple informational and deletion commands
send_incr_decr_cmd(Socket, Cmd) ->
gen_tcp:send(Socket, Cmd ++ "\r\n"),
Reply = recv_incr_decr_reply(),
Reply.
%% @private
%% @doc recv_incr_decr_reply/0 function for increment and decrement responses
recv_incr_decr_reply() ->
receive
{tcp,_,Data} ->
Parse = io_lib:fread("~s\r\n", binary_to_list(Data)),
{ok,[Reply], _} = Parse,
Reply;
{error, closed} ->
connection_closed
after ?TIMEOUT ->
timeout
end.
<snip>
%% @private
%% @doc receive function for respones containing VALUEs
recv_complex_reply(Socket) ->
receive
%% For receiving get responses where the key does not exist
{tcp, Socket, <<"END\r\n">>} -> ["END"];
%% For receiving get responses containing data
{tcp, Socket, Data} ->
%% Reply format <<"VALUE SOMEKEY FLAG BYTES\r\nSOMEVALUE\r\nEND\r\n">>
Parse = io_lib:fread("~s ~s ~u ~u\r\n", binary_to_list(Data)),
{ok,[_,_,_,Bytes], ListBin} = Parse,
Bin = list_to_binary(ListBin),
Reply = get_data(Socket, Bin, Bytes, length(ListBin)),
Reply;
{error, closed} ->
connection_closed
after ?TIMEOUT -> timeout
end.
%% @private
%% @doc recieve loop to get all data
%% @todo
get_data(Socket, Bin, Bytes, Len) when Len < Bytes + 7->
receive
{tcp, Socket, Data} ->
Combined = <<Bin/binary, Data/binary>>,
get_data(Socket, Combined, Bytes, size(Combined));
{error, closed} ->
connection_closed
after ?TIMEOUT -> timeout
end;
get_data(_, Data, Bytes, _) ->
Parse = io_lib:fread("~s\r\n", binary_to_list(Data)),
{ok,[Reply], _} = Parse,
[Reply].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment