Skip to content

Commit

Permalink
MAJOR Update (not yet finished): New configuration system using an XM…
Browse files Browse the repository at this point in the history
…L file. This requires xmerl-0.15

SVN Revision: 123
  • Loading branch information
nniclausse committed Dec 12, 2003
1 parent a25bab1 commit 65af9b8
Show file tree
Hide file tree
Showing 25 changed files with 1,200 additions and 239 deletions.
13 changes: 9 additions & 4 deletions Makefile
Expand Up @@ -12,11 +12,14 @@ prefix = /usr/local/idx-tsunami
# export ERLC_EMULATOR to fix a bug in R9B with native compilation
ERLC_EMULATOR=/usr/bin/erl
export ERLC_EMULATOR
ERL_COMPILER_OPTIONS="[warn_unused_vars]"
export ERL_COMPILER_OPTIONS
OPTIONS:=+debug_info
#OPTIONS:=+native +\{hipe,\[o3\]\}
#OPTIONS:=+export_all
#OPTIONS:=
ERLC = erlc $(OPTIONS)
INC = ./include
ERLC = erlc $(OPTIONS) -I $(INC)
OUTDIR = ebin
ALLERLS:= $(wildcard src/*.erl)
ALLBEAMS:=$(patsubst src/%.erl,$(OUTDIR)/%.beam, $(ALLERLS))
Expand All @@ -41,14 +44,14 @@ clean:
rm -f $(ALLBEAMS) tsunami.boot tsunami.script ebin/tsunami*.app ebin/tsunami*.rel ebin/idx-tsunami.pl ebin/analyse_msg.pl

tsunami.boot: ebin $(ALLBEAMS) $(UTILS) src/tsunami.rel.src src/tsunami.app.src src/analyse_msg.pl.src src/idx-tsunami.pl.src Makefile
sed -e 's;%VSN%;$(VSN);' ./src/tsunami.app.src > ./ebin/tsunami.app
sed -e 's@%VSN%@$(VSN)@;s@%prefix%@$(prefix)@' ./src/tsunami.app.src > ./ebin/tsunami.app
sed -e 's;%VSN%;$(VSN);' ./src/tsunami.rel.src > ./ebin/tsunami.rel
sed -e 's@%VSN%@$(VSN)@;s@%prefix%@$(prefix)@' ./src/idx-tsunami.pl.src > ./ebin/idx-tsunami.pl
sed -e 's;%VSN%;$(VSN);' ./src/analyse_msg.pl.src > ./ebin/analyse_msg.pl
erl -noshell $(PA) ./src -s make_boot make_boot tsunami

tsunami_controller.boot: ebin $(ALLBEAMS) $(UTILS) src/tsunami_controller.rel.src src/tsunami_controller.app.src Makefile
sed -e 's;%VSN%;$(VSN);' ./src/tsunami_controller.app.src > ./ebin/tsunami_controller.app
sed -e 's@%VSN%@$(VSN)@;s@%prefix%@$(prefix)@' ./src/tsunami_controller.app.src > ./ebin/tsunami_controller.app
sed -e 's;%VSN%;$(VSN);' ./src/tsunami_controller.rel.src > ./ebin/tsunami_controller.rel
erl -noshell $(PA) ./src -s make_boot make_boot tsunami_controller

Expand All @@ -66,9 +69,10 @@ install: tsunami.boot tsunami_controller.boot
mkdir -p $(prefix)/bin
mkdir -p $(prefix)/log
mkdir -p $(prefix)/etc
mkdir -p $(prefix)/bin
mkdir -p $(prefix)/erlang/tsunami-$(VSN)/src
install -m 0644 tsunami.boot $(prefix)/bin
install -m 0644 tsunami.boot $(prefix)/bin
install -m 0644 idx-tsunami.xml $(prefix)/etc/idx-tsunami_default.xml
install -m 0644 tsunami_controller.boot $(prefix)/bin
sed -e 's;%prefix%;$(prefix);' idx-tsunamirc > $(prefix)/etc/idx-tsunamirc.default
install ebin/idx-tsunami.pl ${prefix}/bin
Expand All @@ -79,4 +83,5 @@ install: tsunami.boot tsunami_controller.boot
mkdir -p $(prefix)/erlang/tsunami-$(VSN)/ebin
install $(ALLBEAMS) $(prefix)/erlang/tsunami-$(VSN)/ebin
install ebin/*.app $(prefix)/erlang/tsunami-$(VSN)/ebin
install src/*.erl $(prefix)/erlang/tsunami-$(VSN)/src

68 changes: 68 additions & 0 deletions include/ts_config.hrl
@@ -0,0 +1,68 @@
%%%
%%% Copyright © IDEALX S.A.S. 2003
%%%
%%% Author : Nicolas Niclausse <nicolas.niclausse@IDEALX.com>
%%% Created: 03 Dec 2003 by Nicolas Niclausse <nicolas.niclausse@IDEALX.com>
%%%
%%% This program is free software; you can redistribute it and/or modify
%%% it under the terms of the GNU General Public License as published by
%%% the Free Software Foundation; either version 2 of the License, or
%%% (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%%% GNU General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
%%%

-vc('$Id$ ').
-author('nicolas.niclausse@IDEALX.com').

-record(config, {
name,
loglevel = ?WARN,
monitoring = none,
controller, %% controller machine
clients=[], %% client machines

server, %% server to test
arrivalphases =[], %% arrival process specs
thinktime, %% default thinktime specs
sessions=[],
session_tab,
curthink, %% temporary var (current request think)
curid = 0 %% temporary var (current request id)
}).

-record(client,
{host,
weight = 1,
maxusers,
ip = []
}).
-record(server,
{host,
port,
type
}).
-record(session,
{ id,
popularity,
type,
messages_ack = parse,
persistent = false,
size
}).

-record(arrivalphase,
{phase,
duration,
unit,
number, %% ?
intensity,
maxnumber
}).
11 changes: 10 additions & 1 deletion include/ts_http.hrl
Expand Up @@ -21,7 +21,16 @@
-author('nicolas.niclausse@IDEALX.com').

%% use by the client to create the request
-record(http_request, {url, cookie=none, method=get, body=[], id = 0 }).
-record(http_request, {
url,
version="1.1", % default is HTTP/1.1
server_name, % use for the 'Host:' header
get_ims_date = none, % used when the method is getims
cookie=none,
method=get,
body=[],
id = 0
}).

-record(url,
{scheme, %% http, https, ...
Expand Down
3 changes: 2 additions & 1 deletion include/ts_profile.hrl
Expand Up @@ -23,7 +23,6 @@
-record(message, {thinktime,
ack,
param,
type=static,
endpage=false,
host, % override global server hostname
port, % override global server port
Expand Down Expand Up @@ -51,6 +50,8 @@
-define(restart_sleep, 2000).
-define(infinity_timeout, 15000).
-define(short_timeout, 1).
-define(config_timeout, 60000).
-define(check_noclient_timeout, 60000).
-define(retries, 4).

-define(CRLF, "\r\n").
Expand Down
7 changes: 4 additions & 3 deletions src/jabber_dynamic.erl
Expand Up @@ -38,9 +38,10 @@ get_client(N, Id)->
param = #jabber {type = 'authenticate', id = Id}},
#message{ack = no_ack, thinktime=2000+random:uniform(?config(presence_delay)),
param = #jabber {type = 'presence'}},
#message{type= dynamic, ack = no_ack, thinktime=
round(ts_stats:exponential(?messages_intensity)),
param = #jabber {type = 'chat', size= ?config(messages_size), id =Id}},
% FIXME: no more dynamic messages
% #message{type= dynamic, ack = no_ack, thinktime=
% round(ts_stats:exponential(?messages_intensity)),
% param = #jabber {type = 'chat', size= ?config(messages_size), id =Id}},
#message{ack=local, thinktime=infinity, param=#jabber{type = 'close'}}
],
?LOGF("~w~n", [List_Fin], ?DEB),
Expand Down
79 changes: 33 additions & 46 deletions src/ts_client.erl
Expand Up @@ -25,21 +25,22 @@

-behaviour(gen_server).

-include("../include/ts_profile.hrl").
-include("ts_profile.hrl").
-include("ts_config.hrl").

%% External exports
-export([start/1, next/1, close/1]).

%% gen_server callbacks
-export([init/1, init/2, handle_call/3, handle_cast/2, handle_info/2, terminate/2]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]).

-record(state, {rcvpid, % pid of receiving process
server, % name (or IP) of server
port, % server port
protocol, % gen_tcp, gen_udp or ssl
socket, % Socket descriptor
clienttype, % type of client (ts_http11, jabber_online, etc.)
mestype, % type of messages (dynamic or static)
ip, % local ip to bind to
clienttype, % type of client (ts_http, jabber_online, etc.)
profile, % list of requests parameters
persistent, % if true, don't exit when connexion is closed
lasttimeout,% value of the last timeout
Expand Down Expand Up @@ -89,53 +90,41 @@ next({Pid, DynData}) ->
%% ignore |
%% {stop, Reason}
%%----------------------------------------------------------------------
init([{Profile, Size}, {CType, PType, static, Persistent}]) ->
?LOG("Init ... static~n",?DEB),
init([Profile, {CType, PType, static, Persistent}], Size);

init([{Profile, Size}, {CType, PType, dynamic, Persistent}]) ->
?LOG("Init ... dynamic~n",?DEB),
random:seed(),
init([Profile, {CType, PType, static, Persistent}],
?config(messages_number) + Size - 1);

init(Args) ->
?LOGF("Init ... with bad args ~p~n",[Args], ?DEB),
ts_mon:addcount({ badprofile }).


init([Profile, {CType, PType, MType, Persistent}], Count) ->
init({Session=#session{id = Profile,
persistent = Persistent,
messages_ack = PType,
type = CType}, Count, IP}) ->
?LOGF("Init ... started with count = ~p ~n",[Count],?DEB),
%%init seed
% random:seed(ts_utils:init_seed()),
% ?LOG("seed OK ~n",?DEB),
%% random:seed(ts_utils:init_seed()),
case ts_session_cache:get_req(Profile, 1) of
#message{host=undefined, port= undefined, scheme= undefined} ->
?LOG("Server not configured in msg, get global conf ~n",?DEB),
{ServerName, Port, Protocol} = ts_profile:get_server(); % get global server profile
% get global server profile
{ServerName, Port, Protocol} = ts_config_server:get_server_config();
#message{host=ServerName, port= Port, scheme= Protocol} ->
%% server profile can be overriden in the first URL of the session
%% curently, the following server modifications in the session are not used.
?LOGF("Server setup overriden for this client (~p) host=~s port=~p proto=~p ~n",
[self(), ServerName, Port, Protocol], ?INFO);
Other ->
?LOGF("ERROR while getting first req [~p]! ~n",[Other],?ERR),
{ServerName, Port, Protocol} = ts_profile:get_server() % get global server profile
{ServerName, Port, Protocol} = ts_config_server:get_server_config()
end,
?LOG("Got first message, connect ... ~n",?DEB),
% open connection
Opts = protocol_options(Protocol),
Opts = protocol_options(Protocol) ++ [{ip, IP}],
?LOGF("Got first message, connect to ~p with options ~p ~n",
[{ServerName, Port, Protocol},Opts],?DEB),
StartTime= now(),
case Protocol:connect(ServerName, Port, Opts, ?config(connect_timeout)) of
{ok, Socket} ->
% start a new process for receiving messages from the server
case ts_client_rcv:start({PType,
CType, self(),
Socket,
Protocol,
?config(tcp_timeout),
?config(messages_ack),
?config(monitoring)}) of
%% start a new process for receiving messages from the server
case ts_client_rcv:start({ CType, self(),
Socket,
Protocol,
?config(tcp_timeout),
PType,
?config(monitoring)}) of
{ok, Pid} ->
?LOG("rcv server started ~n",?DEB),
controlling_process(Protocol, Socket, Pid),
Expand All @@ -145,11 +134,12 @@ init([Profile, {CType, PType, MType, Persistent}], Count) ->
{ok, #state{rcvpid = Pid, socket = Socket, port = Port,
server= ServerName, profile= Profile,
protocol = Protocol,
clienttype = CType, mestype = MType,
clienttype = CType,
persistent = Persistent,
starttime = StartTime,
monitor = ?config(monitoring),
count = Count,
ip = IP,
maxcount = Count
}, ?short_timeout};
{error, Reason} ->
Expand Down Expand Up @@ -189,13 +179,13 @@ handle_cast({next_msg}, State = #state{lasttimeout = infinity}) ->
?LOGF("next_msg, count is ~p~n", [State#state.count], ?DEB),
{noreply, State#state{lasttimeout=1}, ?short_timeout};
handle_cast({next_msg}, State) ->
?LOG("next_msg (infinite timeout)",?DEB),
?LOGF("next_msg (timeout is set to ~p)",[State#state.lasttimeout],?DEB),
{noreply, State, State#state.lasttimeout};
handle_cast({next_msg, DynData}, State = #state{lasttimeout = infinity}) ->
?LOGF("next_msg, count is ~p~n", [State#state.count], ?DEB),
{noreply, State#state{lasttimeout=1, dyndata=DynData}, ?short_timeout};
handle_cast({next_msg, DynData}, State) ->
?LOG("next_msg (infinite timeout)",?DEB),
?LOGF("next_msg (timeout is set to ~p)",[State#state.lasttimeout],?DEB),
{noreply, State#state{dyndata=DynData}, State#state.lasttimeout};
%% more case to handle ?

Expand Down Expand Up @@ -233,7 +223,7 @@ handle_cast({closed, Pid}, State) ->
{stop, normal, State};

handle_cast({closed, Reason, Pid}, State) ->
?LOGF("Closed after an error while while pending count is: ~p~n!",
?LOGF("Closed after an error while pending count is: ~p~n!",
[State#state.count], ?INFO),
ts_mon:addcount({ Reason }),
{stop, normal, State};
Expand Down Expand Up @@ -290,7 +280,7 @@ handle_info(timeout, State ) ->
end,

%% reconnect if needed
case reconnect(Socket, Host, Port, Protocol, State#state.rcvpid) of
case reconnect(Socket, Host, Port, Protocol, State#state.ip, State#state.rcvpid) of
{ok, NewSocket} ->
%% warn the receiving side that we are sending a new request
ts_client_rcv:wait_ack({State#state.rcvpid,Profile#message.ack, Now,
Expand Down Expand Up @@ -335,6 +325,7 @@ handle_info(timeout, State ) ->
%% Returns: any (ignored by gen_server)
%%----------------------------------------------------------------------
terminate(Reason, State) ->
%% FIXME : check Reason and report anormal return values to ts_mon
?LOGF("Stop, reason= ~p~n",[Reason],?INFO),
Now = now(),
Elapsed = ts_utils:elapsed(State#state.starttime, Now),
Expand All @@ -354,12 +345,8 @@ terminate(Reason, State) ->
%% static message, get the thinktime from profile
set_profile(MaxCount, Count, ProfileId) when integer(ProfileId) ->
set_profile(MaxCount, Count, ts_session_cache:get_req(ProfileId, MaxCount-Count+1));
set_profile(MaxCount, Count, Profile=#message{type = static}) ->
{Profile#message.thinktime, Profile };
%% dynamic message, last message
%% FIXME: don't work anymore: when do we stop ?
set_profile(MaxCount, Count, Profile) ->
{ts_profile:thinktime(), Profile }.
{Profile#message.thinktime, Profile }.

%%----------------------------------------------------------------------
%% Func: new_timeout/3
Expand All @@ -379,7 +366,7 @@ new_timeout(_Else, _Count, Thinktime) -> infinity.
%%----------------------------------------------------------------------
reconnect(none, ServerName, Port, Protocol, Pid) ->
?LOGF("Try to reconnect to: ~p (~p)~n",[ServerName, Pid], ?DEB),
Opts = protocol_options(Protocol),
Opts = protocol_options(Protocol) ++ [{ip, IP}],
case Protocol:connect(ServerName, Port, Opts) of
{ok, Socket} ->
controlling_process(Protocol, Socket, Pid),
Expand All @@ -391,7 +378,7 @@ reconnect(none, ServerName, Port, Protocol, Pid) ->
ts_mon:addcount({ list_to_atom(CountName) }),
{stop, connfailed}
end;
reconnect(Socket, Server, Port, Protocol, Pid) ->
reconnect(Socket, Server, Port, Protocol, IP, Pid) ->
{ok, Socket}.

%% close socket if it exists
Expand Down
6 changes: 3 additions & 3 deletions src/ts_client_rcv.erl
Expand Up @@ -57,7 +57,7 @@ wait_ack({Pid, Ack, When, EndPage, Socket, Protocol}) ->
%% ignore |
%% {stop, Reason}
%%----------------------------------------------------------------------
init([{PType, CType, PPid, Socket, Protocol, Timeout, Ack, Monitor}]) ->
init([{CType, PPid, Socket, Protocol, Timeout, Ack, Monitor}]) ->
{ok, #state_rcv{socket = Socket, timeout= Timeout, ack = Ack,
ppid= PPid, clienttype = CType, protocol= Protocol,
session = ts_profile:new_session(CType, Ack),
Expand Down Expand Up @@ -128,7 +128,7 @@ handle_info({ssl, Socket, Data}, State) ->
{noreply, NewState, State#state_rcv.timeout};

handle_info({tcp_closed, Socket}, State) ->
?LOG("TCP close: ~n", ?NOTICE),
?LOG("TCP close: ~n", ?INFO),
ts_client:close(State#state_rcv.ppid),
{noreply, State};

Expand All @@ -139,7 +139,7 @@ handle_info({tcp_error, Socket, Reason}, State) ->
{noreply, State};

handle_info({ssl_closed, Socket}, State) ->
?LOG("SSL close: ~n", ?NOTICE),
?LOG("SSL close: ~n", ?INFO),
ts_client:close(State#state_rcv.ppid),
{noreply, State};

Expand Down

0 comments on commit 65af9b8

Please sign in to comment.