<HTML><BODY style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><BR><DIV><DIV>On 28 Mar 2006, at 15:41, <A href="mailto:mark@unhinged.eclipse.co.uk">mark@unhinged.eclipse.co.uk</A> wrote:</DIV><BR class="Apple-interchange-newline"><BLOCKQUOTE type="cite"><P style="margin: 0.0px 0.0px 0.0px 0.0px"><FONT face="Helvetica" size="3" style="font: 12.0px Helvetica">Ok, me being daft there. So how can I handle the timeout? I don't want</FONT></P> <P style="margin: 0.0px 0.0px 0.0px 0.0px"><FONT face="Helvetica" size="3" style="font: 12.0px Helvetica">the gen_server to die when the call exceeds the timeout, I just want to</FONT></P> <P style="margin: 0.0px 0.0px 0.0px 0.0px"><FONT face="Helvetica" size="3" style="font: 12.0px Helvetica">be able to reflect that this has happened.</FONT></P> </BLOCKQUOTE></DIV><BR><DIV>Have a look at this:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>-module(s).</DIV><DIV>-compile(export_all).</DIV><DIV>-define(SERVER,srv).</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>start() -> gen_server:start({local,?SERVER}, ?MODULE, [], []).</DIV><DIV>start_link() -> gen_server:start_link({local,?SERVER}, ?MODULE, [], []).</DIV><DIV>fail() -> gen_server:call(?SERVER, slowcall, 1).</DIV><DIV>safe() -> case catch fail() of</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN> {'EXIT', Reason} -> {error, Reason};</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN> Other -> {ok, Other}</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN> end.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>init([]) -> {ok, []}.</DIV><DIV>handle_call(slowcall,_,State) -></DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>receive after 100 -> x end,</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>{reply, ok, State}.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>There are a few ways of running it. Here's what you were doing:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Eshell V5.4.13 (abort with ^G)</DIV><DIV>1> s:start_link().</DIV><DIV>{ok,<0.37.0>}</DIV><DIV>2> s:fail(). </DIV><DIV>** exited: {timeout,{gen_server,call,[srv,slowcall,1]}} **</DIV><DIV>3> s:fail().</DIV><DIV>** exited: {noproc,{gen_server,call,[srv,slowcall,1]}} **</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>What's happening here is that you're using the shell to start your gen_server process. You end up linking the shell process to the gen_server process which means that if that the shell process dies, it takes down the gen_server with it. The default shell behaviour is that if it executes a function which fails, it exits and a new "replacement shell" process is spawned off to carry on. This is what's happening here. Your first call to s:fail() does just that - it fails. The gen_server was fine at that point... it didn't crash until it got brought down by the shell exiting (because the two processes are linked).</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Here's another way of running the example:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>1> s:start().</DIV><DIV>{ok,<0.37.0>}</DIV><DIV>2> s:fail().</DIV><DIV>** exited: {timeout,{gen_server,call,[srv,slowcall,1]}} **</DIV><DIV>3> s:fail().</DIV><DIV>** exited: {timeout,{gen_server,call,[srv,slowcall,1]}} **</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Again, the fail() function fails, but this time the shell process dying doesn't cause the gen_server to terminate. At the end of this example it's still alive and well and processing requests.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Another way is this:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Eshell V5.4.13 (abort with ^G)</DIV><DIV>1> s:start_link().</DIV><DIV>{ok,<0.37.0>}</DIV><DIV>2> s:safe().</DIV><DIV>{error,{timeout,{gen_server,call,[srv,slowcall,1]}}}</DIV><DIV>3> s:safe().</DIV><DIV>{error,{timeout,{gen_server,call,[srv,slowcall,1]}}}</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>This time, although the shell process is linked to the gen_server, I've caught the error from the fail() function and so the shell didn't exit. Thus, it didn't cause the gen_server to die.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>All three approaches are equally valid in different situations. Joe Armstrong's book (and his PhD thesis) gives examples of when you'd want to link processes together and when you wouldn't. Also, although there *is* a "catch" keyword in Erlang it's used surprisingly rarely. Catching all errors like this sometimes isn't actually terribly helpful, and it's certainly not something the language just makes you do to be awkward (religiously wrapping every possible things which could fail with a catch statement to prevent any knock-on effect for any processes linked to it - although I have seen Java programmers do things like this).</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>You need to have a strategy of which processes should die if a call to the gen_server doesn't succeed. There could be instances where you return a "Sorry, system can't cope with the load at the moment" to the end user and press on regardless. On the other hand you might be talking about a realtime system where the gen_server can't and shouldn't take that long to reply. If that's the case then you'd probably want to ask the gen_server to crash (crashing is a _good_ thing in Erlang), shutdown cleanly, and then arrange for it to be restarted (by a supervisor) to get it into a decent state in order to continue processing requests. This is the Erlang "let it crash" approach.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>The OTP design principles document is probably the best starting point for all this stuff:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><A href="http://erlang.se/doc/doc-5.4.12/doc/design_principles/part_frame.html">http://erlang.se/doc/doc-5.4.12/doc/design_principles/part_frame.html</A></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Richard.</DIV></BODY></HTML>