[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