[erlang-questions] Troubleshooting using YAWS + SOAP
Laura M. Castro Souto
lcastro@REDACTED
Thu Jul 19 17:19:27 CEST 2007
Hello all,
It seems that we finally found the source of the problem. In the end, it has
something to do with yaws_soap_srv module, which is the genserver that was
dying with the timeout error. And the reason was in front of our eyes all the
time, as happens so many times. Let me explain it here for the record.
Remember the "minimal" server that Willem posted in his mail?
> -module(my_soap).
> -export([handler/4]).
>
> -record('p:CodigoVO', {anyAttribs, 'etiqueta', 'valor'}).
> -record('p:setParte', {anyAttribs, 'param0', 'param1', 'param2', 'param3',
> 'param4', 'param5', 'param6'}).
> -record('p:setParteResponse', {anyAttribs, 'return'}).
>
> handler(_Header,
> [#'p:setParte'{'param0' = P0}],
> _Action,
> _SessionValue) ->
> {ok, undefined, setParte(P0)}.
>
> setParte(P0) ->
> CodigoVO = #'p:CodigoVO'{'etiqueta' = P0, 'valor' = 1},
> #'p:setParteResponse'{'return' = CodigoVO}.
As Willem said, this server works out perfectly well, but this is just
because is *that minimal*. The issue is that the operation being invoked
through the web service (setParte) might not be *that simple*, meaning that
it could potentially be a function that consumes some time to get its result.
If "some time" is less than 5000 milliseconds, everything is fine. But what
happens if it's not? Well, the yaws_soap_srv genserver dies. As simple as
that. Why? Because whenever the gen_server:call function is used inside that
module, its third optional parameter (Timeout) is never specified, thus
assuming a default value (guess what: 5000 milliseconds). Check out the
source code:
handler(Args, Id, Payload, SessionValue) ->
(...)
case gen_server:call(?SERVER, {request, Id, Payload,
SessionValue,
SoapAction})
of
{ok, XmlDoc, ResCode, undefined} ->
{false, XmlDoc, ResCode};
{ok, XmlDoc, ResCode, SessVal} ->
{true, 0, SessVal, XmlDoc, ResCode};
{error, _, _} = Error ->
Error;
false ->
false
end.
So what we did is to add the third parameter to the gen_server:call function
and now everything is working!
handler(Args, Id, Payload, SessionValue) ->
(...)
case gen_server:call(?SERVER, {request, Id, Payload,
SessionValue,
SoapAction},
infinity)
of
{ok, XmlDoc, ResCode, undefined} ->
{false, XmlDoc, ResCode};
{ok, XmlDoc, ResCode, SessVal} ->
{true, 0, SessVal, XmlDoc, ResCode};
{error, _, _} = Error ->
Error;
false ->
false
end.
I understand that an infinite timeout might not be reasonable in all cases,
maybe even in most of the cases, but you will agree with me that the need for
a timeout greather than 5000 might not be that strange...
Perhaps, a general solution for this will be to let the client modules of
yaws+soap configure that timeout option, maybe by means of another field in
the gconf struct.
Regards,
--
Laura M. Castro
MADS Group - Computer Science Department
University of A Corunna
http://www.madsgroup.org/staff/laura/index_en.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070719/2bcdc5ca/attachment.bin>
More information about the erlang-questions
mailing list