Skip to content

Instantly share code, notes, and snippets.

@valinurovam
Created September 17, 2012 16:55
Show Gist options
  • Save valinurovam/3738457 to your computer and use it in GitHub Desktop.
Save valinurovam/3738457 to your computer and use it in GitHub Desktop.
-module(smpp_queue_server).
-behaviour(gen_server).
-define(SERVER, ?MODULE).
-define(QUEUE, smpp_queue).
%%% RECORDS
-record(status, {
queue_length = 0
}
).
%% ------------------------------------------------------------------
%% API Function Exports
%% ------------------------------------------------------------------
-export([
start_link/0,
stop/0,
state/0,
queue_add_item/1]).
%% ------------------------------------------------------------------
%% gen_server Function Exports
%% ------------------------------------------------------------------
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
%% ------------------------------------------------------------------
%% API Function Definitions
%% ------------------------------------------------------------------
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
stop() ->
gen_server:call(?MODULE, stop).
queue_add_item({Key, Value}) ->
gen_server:cast(?MODULE, {queue_add_item, Key, Value}).
state() ->
gen_server:call(?MODULE, state).
%% ------------------------------------------------------------------
%% gen_server Function Definitions
%% ------------------------------------------------------------------
init(_Args) ->
ets:new(?QUEUE, [named_table, bag]),
self() ! queue_loop,
{ok, #status{queue_length = 0}}.
handle_call(state, _From, State) ->
io:format("~p~n", [State]),
{reply, ok, State};
handle_call(stop, _From, State) ->
{stop, normal, ok, State};
handle_call(_Request, _From, State) ->
{reply, ok, State}.
handle_cast({queue_add_item, Key, Value}, State) ->
ets:insert(?QUEUE, {Key, Value}),
{noreply, State#status{queue_length = State#status.queue_length + 1}}.
handle_info(queue_loop, State) ->
self() ! {queue_loop, ets:first(?QUEUE)},
{noreply, State};
handle_info({queue_loop, '$end_of_table'}, State) ->
erlang:send_after(1000, self(), {queue_loop, ets:first(?QUEUE)}),
{noreply, State};
handle_info({queue_loop, Key}, State) ->
case ets:lookup(?QUEUE, Key) of
Rows = [{{_PI, _SA, _DA, _UR, UdhTotal}, _Value} | _Tail] ->
case UdhTotal =:= length(Rows) of
false ->
self() ! {queue_loop, ets:next(?QUEUE, Key)};
true ->
NextKey = ets:next(?QUEUE, Key),
ets:delete(?QUEUE, Key),
self() ! {queue_loop, NextKey}
end;
[] ->
self() ! {queue_loop, ets:next(?QUEUE, Key)}
end,
{noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% ------------------------------------------------------------------
%% Internal Function Definitions
%% ------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment