[Tsung] Re: keepalive packets
Jason Tucker
jasonwtucker at gmail.com
Fri May 18 18:24:33 CEST 2007
On 5/17/07, Jason Tucker <jasonwtucker at gmail.com> wrote:
>
> I'm seeing an odd problem that is very hard to replicate, but I think it
> may have to do with keepalive messages being sent by the XMPP server...
>
> I'm running a transaction that expects a response from the server in order
> to populate a dynvar. I suspect that in rare cases, under high load, it is
> possible for a server keepalive message to beat the expected response
> message back to the client. In this case, the client would try to parse the
> keepalive message and fail to populate the dynvar, no? Is this a possiblity?
>
>
> And if so, is there a way to modify the client code to basically ignore
> the keepalives? BTW, the keepalive message is essentially just a "space"
> character sent across the stream. So, if my suspicions are correct, what we
> want to do is modify the client so that it will not pass messages less than
> 2 bytes in size to ts_search.
>
> Thoughts?
I *think* I found a fix for this condition in ts_client.erl. Here is the
original code:
%% local ack, set ack_done to true
handle_data_msg(Data, State=#state_rcv{request=Req, maxcount= MaxCount}) ->
ts_mon:rcvmes({State#state_rcv.dump, self(), Data}),
NewBuffer= set_new_buffer(Req, State#state_rcv.buffer, Data),
DataSize = size(Data),
{PageTimeStamp, DynVars} = update_stats(State#state_rcv{datasize=DataSize,
buffer=NewBuffer}),
NewCount = ts_search:match(Req#ts_request.match, NewBuffer,
{State#state_rcv.count,MaxCount}),
NewDynData = concat_dynvars(DynVars, State#state_rcv.dyndata),
{State#state_rcv{ack_done = true, buffer= NewBuffer, dyndata = NewDynData,
page_timestamp= PageTimeStamp, count=NewCount},[]}.
And here is the change I made - I just added an if statement which checks
size(Data) :
%% local ack, set ack_done to true
handle_data_msg(Data, State=#state_rcv{request=Req, maxcount= MaxCount}) ->
ts_mon:rcvmes({State#state_rcv.dump, self(), Data}),
NewBuffer= set_new_buffer(Req, State#state_rcv.buffer, Data),
DataSize = size(Data),
{PageTimeStamp, DynVars} = update_stats(State#state_rcv{datasize=DataSize,
buffer=NewBuffer}),
NewCount = ts_search:match(Req#ts_request.match, NewBuffer,
{State#state_rcv.count,MaxCount}),
NewDynData = concat_dynvars(DynVars, State#state_rcv.dyndata),
if
size(Data) < 2 ->
%% our dyndata must in a packet larger than 1 byte, set
ack_done to false
{State#state_rcv{ack_done = false, buffer= NewBuffer,
dyndata = NewDynData,
page_timestamp= PageTimeStamp, count=NewCount},[]};
true ->
%% this packet is a candidate to contain dyndata, set
ack_done to true
{State#state_rcv{ack_done = true, buffer= NewBuffer,
dyndata = NewDynData,
page_timestamp= PageTimeStamp, count=NewCount},[]}
end.
I'm still testing this, but so far, it seems to work. If the client is
expecting a server response to populate a dynvar, and a keepalive packet
comes in first, the client will just keep waiting for a properly sized
packet to fulfill the local_ack requirement.
__Jason
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.process-one.net/pipermail/tsung-users/attachments/20070518/e6d9764c/attachment.html
More information about the Tsung-users
mailing list