Skip to content

Commit

Permalink
Merge pull request #106 from fenek/latency
Browse files Browse the repository at this point in the history
XMPP message latency measurement
  • Loading branch information
nniclausse committed Dec 1, 2014
2 parents 91d08e6 + 0c37ad4 commit b9d9a4d
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 2 deletions.
21 changes: 21 additions & 0 deletions docs/conf-sessions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,27 @@ Here is an example of a session definition for the Jabber/XMPP protocol:
</session>
</sessions>
Message stamping
""""""""

It is possible to stamp chat message by setting ``stamped`` attribute of
``<jabber>`` element inside request to ``true``. The stamp will include current
timestamp and ID of the sender node. If the recipient will recognise the node ID,
it will compare the timestamp inside message with the current one. The difference
will be reported as ``xmpp_msg_latency`` metric (in milliseconds).
The aim of node ID comparison is to avoid slight inconsistencies
of timestamps on different Tsung nodes.

Only a fraction of requests will hit the same node they originated from,
but with request rate high enough this fraction should be sufficient.

``stamped`` is allowed only with ``size`` attribute. ``data`` will cause
``stamped`` to be ignored. There is a minimal length of the stamp,
roughly 30 bytes. When ``size`` is greater than stamp length, random
padding will be added to the stamp. If the stamp length is higher than
``size``, then only stamp will be used as messagecontent, effectively
exceeding specified length.

StartTLS
""""""""

Expand Down
1 change: 1 addition & 0 deletions include/ts_jabber.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
size,
data,
type,
stamped = false,
jud_param,
regexp,
cle,
Expand Down
18 changes: 18 additions & 0 deletions src/tsung/ts_jabber.erl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
userid/1]).

-export ([starttls_bidi/2,
message_bidi/2,
presence_bidi/2]).

%%----------------------------------------------------------------------
Expand Down Expand Up @@ -165,6 +166,7 @@ parse_bidi(Data, State) ->
RcvdXml = binary_to_list(Data),
BidiElements =
[{"<presence[^>]*subscribe[\"\']", presence_bidi},
{"@@@([^@]+)@@@", message_bidi},
{"<proceed", starttls_bidi}],
lists:foldl(fun({Regex, Handler}, Acc)->
case re:run(RcvdXml,Regex) of
Expand All @@ -180,6 +182,22 @@ presence_bidi(RcvdXml, State)->
{match,SubMatches} = re:run(RcvdXml,"<presence[^>]*subscribe[\"\'][^>]*>",[global]),
bidi_resp(subscribed,RcvdXml,SubMatches,State).

message_bidi(RcvdXml, State) ->
{match, [NodeStamp]} = re:run(RcvdXml, "@@@([^@]+)@@@", [{capture, all_but_first, list}]),
[NodeS, StampS] = string:tokens(NodeStamp, ","),
case integer_to_list(erlang:phash2(node())) of
NodeS ->
[MegaS, SecsS, MicroS] = string:tokens(StampS, ";"),
Mega = list_to_integer(MegaS),
Secs = list_to_integer(SecsS),
Micro = list_to_integer(MicroS),
Latency = timer:now_diff(erlang:now(), {Mega, Secs, Micro}),
ts_mon:add({ sample, xmpp_msg_latency, Latency / 1000});
_ ->
ignore
end,
{nodata, State}.

starttls_bidi(_RcvdXml, #state_rcv{socket= Socket}=State)->
ssl:start(),
Req = subst(State#state_rcv.request#ts_request.param, State#state_rcv.dynvars),
Expand Down
20 changes: 18 additions & 2 deletions src/tsung/ts_jabber_common.erl
Original file line number Diff line number Diff line change
Expand Up @@ -481,19 +481,35 @@ registration(#jabber{username=Name,passwd=Passwd,resource=Resource})->
%% Func: message/3
%% Purpose: send message to defined user at the Service (aim, ...)
%%----------------------------------------------------------------------
message(Dest, #jabber{size=Size,data=undefined}, Service) when is_integer(Size) ->
message(Dest, #jabber{size=Size,data=undefined,stamped=Stamped}, Service) when is_integer(Size) ->
Stamp = generate_stamp(Stamped),
PadLen = Size - length(Stamp),
Data = case PadLen > 0 of
true -> ts_utils:urandomstr_noflat(PadLen);
false -> ""
end,
StampAndData = Stamp ++ Data,
put(previous, Dest),
list_to_binary([
"<message id='",ts_msg_server:get_id(list), "' to='",
Dest, "@", Service,
"' type='chat'><body>",ts_utils:urandomstr_noflat(Size), "</body></message>"]);
"' type='chat'><body>",StampAndData, "</body></message>"]);
message(Dest, #jabber{data=Data}, Service) when is_list(Data) ->
put(previous, Dest),
list_to_binary([
"<message id='",ts_msg_server:get_id(list), "' to='",
Dest, "@", Service,
"' type='chat'><body>",Data, "</body></message>"]).

generate_stamp(false) ->
"";
generate_stamp(true) ->
{Mega, Secs, Micro} = erlang:now(),
TS = integer_to_list(Mega) ++ ";"
++ integer_to_list(Secs) ++ ";"
++ integer_to_list(Micro),
"@@@" ++ integer_to_list(erlang:phash2(node())) ++ "," ++ TS ++ "@@@".

%%----------------------------------------------------------------------
%% Func: presence/0
%%----------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions src/tsung_controller/ts_config_jabber.erl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ parse_config(Element = #xmlElement{name=jabber},
TypeStr = ts_config:getAttr(string,Element#xmlElement.attributes, type, "chat"),
Ack = ts_config:getAttr(atom,Element#xmlElement.attributes, ack, no_ack),
Dest= ts_config:getAttr(atom,Element#xmlElement.attributes, destination,random),
Stamped = ts_config:getAttr(atom,Element#xmlElement.attributes, stamped, false),

Size= ts_config:getAttr(integer,Element#xmlElement.attributes, size,0),
Data= ts_config:getAttr(string,Element#xmlElement.attributes, data,undefined),
Expand Down Expand Up @@ -137,6 +138,7 @@ parse_config(Element = #xmlElement{name=jabber},
id = XMPPId,
data = Data,
type = Type,
stamped = Stamped,
regexp = RE,
dest = Dest,
size = Size,
Expand Down
1 change: 1 addition & 0 deletions tsung-1.0.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ repeat | if | change_type | foreach | set_option | interaction )*>
size NMTOKEN "0"
data CDATA #IMPLIED
type NMTOKEN #REQUIRED
stamped (true | false) "false"
show (away|chat|dnd|xa) "chat"
status CDATA "Available"
nick CDATA #IMPLIED
Expand Down

0 comments on commit b9d9a4d

Please sign in to comment.