Napisałem sobie moduł obsługujący bazę danych.
%%% -------------------------------------------------------------------
%%% Author : Johny
%%% Description : obsługa DB postgres
%%%
%%% Created : 11-04-2012
%%% -------------------------------------------------------------------
-module(cs_DB).
-behaviour(gen_server).
%% --------------------------------------------------------------------
%% Include files
%% --------------------------------------------------------------------
%% --------------------------------------------------------------------
%% External exports
-export([start_link/0,insert_timestamp/4]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-record(state, {db}).
%% ====================================================================
%% External functions
%% ====================================================================
-define(HOST, "127.0.0.1").
-define(DB, "db").
-define(USER, "XXX").
-define(PASS, "YYY").
-define(DATABASE, "ZZZ").
start_link() ->
State = #state{},
gen_server:start_link({local, ?MODULE}, ?MODULE, State, []).
%% ====================================================================
%% Server functions
%% ====================================================================
%%
%% Zapis czasu obslugi
insert_timestamp(ID,Timestamp1,Timestamp2,Typ) ->
gen_server:call(?MODULE, {insert_timestamp,ID,Timestamp1,Timestamp2,Typ} ).
%% --------------------------------------------------------------------
%% Function: init/1
%% Description: Initiates the server
%% Returns: {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% --------------------------------------------------------------------
init(State) ->
case pgsql:connect(?HOST, ?USER, ?PASS, [{database, ?DATABASE}]) of
{ok, DB} ->
{ok, #state{db = DB}};
Unkn ->
error_logger:error_msg("Connectiont: ~p",[Unkn]),
{false}
end.
%% --------------------------------------------------------------------
%% Function: handle_call/3
%% Description: Handling call messages
%% Returns: {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} | (terminate/2 is called)
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_call({insert_timestamp,ID,T1 ,T2 ,Typ}, State) ->
%%przeliczam na timestamp z ms
T3 = T2 - T1,
Query = io_lib:format("INSERT INTO \"statystyki\" (serialid, timestamp1, timestamp2, timestamp, typ) VALUES (~p,~p , ~p,~p,~p)",[ID,T1,T2,T3,Typ]),
Reply = case pgsql:squery(State#state.db,Query) of
{ok, X} ->
ok;
_->
error
end,
{reply, Reply, State};
handle_call(Request, From, State) ->
Reply = ok,
{reply, Reply, State}.
%% --------------------------------------------------------------------
%% Function: handle_cast/2
%% Description: Handling cast messages
%% Returns: {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_cast(Msg, State) ->
{noreply, State}.
%% --------------------------------------------------------------------
%% Function: handle_info/2
%% Description: Handling all non call/cast messages
%% Returns: {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_info(Info, State) ->
{noreply, State}.
%% --------------------------------------------------------------------
%% Function: terminate/2
%% Description: Shutdown the server
%% Returns: any (ignored by gen_server)
%% --------------------------------------------------------------------
terminate(Reason, State) ->
ok.
%% --------------------------------------------------------------------
%% Func: code_change/3
%% Purpose: Convert process state when code is changed
%% Returns: {ok, NewState}
%% --------------------------------------------------------------------
code_change(OldVsn, State, Extra) ->
{ok, State}.
%% --------------------------------------------------------------------
%%% Internal functions
%% --------------------------------------------------------------------
Kod działa prawidłowo i nie ma z nim raczej problemów od strony funkcjonalnej. Schody zaczynają się jednak w momencie napływu dużej ilości informacji. Do obsługi DB wykorzystany został pgsql. Moduł ten działa i tutaj z nim raczej nie ma problemu. Puszczając w pętli wpisywanie danych do bazy spokojnie osiąga 1000 wpisów na sekundę. Ale jak tylko wykorzystałem gen_server to maksymalną wartość jaką udało mi się wyciągnąć to 150 wpisów/s. Dlaczego to tak wolno działa? Spotkał się ktoś z was z takim problemem?
Zastanawiam się również czy problemem nie jest sam sposób testowania. Wszystkie operacje wykonywane są na dość leciwym PC z tylko jednym rdzeniem.