Erlang Mailing Lists

Author Message

<  Erlang questions mailing list  ~  Programming question

Guest
Posted: Thu Jan 25, 2007 12:37 pm Reply with quote
Guest
On 25 Jan 2007, at 12:08, Mats Cronqvist wrote:

> Sean Hinde wrote:
>>
>> On 25 Jan 2007, at 08:23, Mats Cronqvist wrote:
>>
>>> Sean Hinde wrote:
>>>>
>>>> One fix might be for gen:call() to issue another exit signal
>>>> towards
>>>> the calling process after returning the result.
>>>
>>> surely if you catch the exit and it turns out you really
>>> wanted it,
>>> you
>>> should re-throw?
>>>
>>> how about
>>>
>>> try
>>> Res = gen_server:call(PidA, {op, stuff}),
>>> S1 = process(Res, S),
>>> loopB(PidA, S1)
>>> catch
>>> C:R ->
>>> case is_process_alive(PidA) of
>>> true -> loopB(PidA,dosomething({C,R},S));
>>> false -> exit({C,R})
>>> end
>>> end
>>
>> This would work, but my is it ugly -
>
> hey! it took me several seconds to write that code! some respect
> please :>

Heh Heh. OK, It's beautiful code, if it makes you feel better, but as
a required construct it is still ugly Smile


>>
>> The problem as I see it is that the calling process only sometimes
>> get
>> its 'EXIT' message - it depends on context.
>
> but it does get it's exit message. always. the "context" is that
> you catch it
> and throw it away...

No! Receiving an exit message is different to catching an exception.
The problem is that the gen_server:call mechanism does just that, it
catches an exit message from the called process and turns it into a
simple exception.

This is why I suggest that *if* the exception thrown by
gen_server:call was actually caused by an exit message from the
called process then the gen_server should throw the exception *and*
resend the EXIT message to the called process.

Sean



_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
Guest
Posted: Thu Jan 25, 2007 12:44 pm Reply with quote
Guest
Sean Hinde wrote:
> On 25 Jan 2007, at 08:23, Mats Cronqvist wrote:
>> try
>> Res = gen_server:call(PidA, {op, stuff}),
>> S1 = process(Res, S),
>> loopB(PidA, S1)
>> catch
>> C:R ->
>> case is_process_alive(PidA) of
>> true -> loopB(PidA,dosomething({C,R},S));
>> false -> exit({C,R})
>> end
>> end
>
> This would work, but my is it ugly - how is anyone supposed to
> remember to do that every time they want to be sure that the called
> process has gone down (as opposed to any other reason for the call to
> thrown an exception).
>
> The problem as I see it is that the calling process only sometimes
> get its 'EXIT' message - it depends on context.

If you have a library that uses the RPC model, as in the case of
'gen_server:call(...)', it is probably a bad idea to try to solve the
problems with RPC that have been known for ages, such as "what do I do
if the server goes down", by adding some ad-hoc handling code to every
remote call. (It can and will be screwed up anyway.) I think that the
interface should be used as it was intended (treating exceptions due to
server-down as any other exception out from the call), and that
additional supervision should be placed somewhere else, outside the
main program logic.

Sean is basically right here: he _ought_ to be able to use normal
links for this purpose (after all, links are the central built-in
"additional supervision" method in Erlang), regardless of whether
the implementation of gen_server:call() does things with links and
trapping of signals: that stuff should have been made transparent to
the user, but is obviously not. (One problem is that there can only
be a single link between two processes, so gen_server can't know
whether or not it should re-issue the caught signal to the caller.)

If this aspect of gen_server (and similar library functions) cannot
be fixed, e.g. by using monitors instead of links, then at a minimum it
should be documented that the functions will steal exit signals if you
try to link directly to the server.

Meanwhile, the fix I suggested previously should work fine: use an
intermediate process, whose signals the gen_server library does not
interfere with.

/Richard

_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
mats
Posted: Thu Jan 25, 2007 1:08 pm Reply with quote
User Joined: 28 Feb 2005 Posts: 168 Location: budapest,hungary
Sean Hinde wrote:
> No! Receiving an exit message is different to catching an exception. The
> problem is that the gen_server:call mechanism does just that, it catches
> an exit message from the called process and turns it into a simple
> exception.
>
> This is why I suggest that *if* the exception thrown by gen_server:call
> was actually caused by an exit message from the called process then the
> gen_server should throw the exception *and* resend the EXIT message to
> the called process.

my bad. you are obviously correct.

mats
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
View user's profile Send private message MSN Messenger
Guest
Posted: Thu Jan 25, 2007 4:36 pm Reply with quote
Guest
On 25 Jan 2007, at 12:35, Richard Carlsson wrote:

> Sean Hinde wrote:
>>
>> The problem as I see it is that the calling process only
>> sometimes get its 'EXIT' message - it depends on context.
>
> If you have a library that uses the RPC model, as in the case of
> 'gen_server:call(...)', it is probably a bad idea to try to solve the
> problems with RPC that have been known for ages, such as "what do I do
> if the server goes down", by adding some ad-hoc handling code to every
> remote call. (It can and will be screwed up anyway.) I think that the
> interface should be used as it was intended (treating exceptions
> due to
> server-down as any other exception out from the call), and that
> additional supervision should be placed somewhere else, outside the
> main program logic.
>
> Sean is basically right here: he _ought_ to be able to use normal
> links for this purpose (after all, links are the central built-in
> "additional supervision" method in Erlang), regardless of whether
> the implementation of gen_server:call() does things with links and
> trapping of signals: that stuff should have been made transparent to
> the user, but is obviously not. (One problem is that there can only
> be a single link between two processes, so gen_server can't know
> whether or not it should re-issue the caught signal to the caller.)

Actually it can, because gen_server can rely solely on monitor for
its own purposes. If it gets an 'EXIT' message then it can be certain
that it is because the two processes have been explicitly linked.

I would be happy to have a compatibility mode for dealing with old
nodes, but I think the default behaviour should for gen_server to
selectively receive its own 'DOWN' message, and leave the EXIT
message on the queue.


>
> If this aspect of gen_server (and similar library functions) cannot
> be fixed, e.g. by using monitors instead of links, then at a
> minimum it
> should be documented that the functions will steal exit signals if you
> try to link directly to the server.

I agree with the documentation comment. It was extremely surprising
the first time I saw this behaviour. It resulted in several outages
of live systems where processes were not restarted simply because of
when they died (not code written by me, so at least two folks have
had this problem). There must be many other systems out there that
are just waiting to suffer the same fate.

>
> Meanwhile, the fix I suggested previously should work fine: use an
> intermediate process, whose signals the gen_server library does not
> interfere with.

To require a 3rd process between the two linked process just to
propogate the EXIT seems like extreme overkill. In my current
application the two process are dynamically created per call - this
would add a 50% overhead to every request.

I don't buy the backwards compatibility argument for this unintuitive
and IMO buggy behaviour. If we look at the cases:

1. Two processes are not linked.

Today - if the other process dies during the call then gen:call()
just throws an exception.
With my change - exactly the same

2. Two processes are linked, with the gen:call not wrapped in a catch

Today - if the other process dies during the call it throws an
exception and the local process dies
With my change - same result, the 'EXIT' message arrives later after
the caller died

3. Two processes are linked, gen:call wrapped in a catch, trapexit =
true

Today - if the other process dies during the call then an exception
is caught. There is no 'EXIT' message, even though this has to be
handled if the linked process dies at any other time.
With my change - The same exception is raised from the call, but the
existing 'EXIT' message handling will also be invoked. - To me this
is a pure bug fix

4. Two processes are linked, gen:call wrapped in a catch, trapexit =
false

Today - Exception is raised as normal, and the calling process lives on.
With proposed change: Exception is raised as normal but the calling
process is killed later by the 'EXIT' signal.

This last case could be seen as a backwards compatibility problem,
but given that the called process can potentially die at any time
outside the call, I would say that the gen_server behaviour is just
hiding a latent bug in the original code, which is likely to happen
at some point anyway.

Worst case we could have a separate call defined with the new behaviour

Sean




_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
uwiger
Posted: Thu Jan 25, 2007 5:29 pm Reply with quote
User Joined: 03 Jul 2006 Posts: 604 Location: Sweden
> To require a 3rd process between the two linked process just
> to propogate the EXIT seems like extreme overkill. In my
> current application the two process are dynamically created
> per call - this would add a 50% overhead to every request.

To be fair, this would be 50% overhead on the cost of
spawning processes, which is about 5-10 us/spawn.
It is hardly noticeable in most cases.

I agree that gen_server shouldn't touch the EXIT
messages. While changing this might cause some
consternation among a few users with legacy code,
I believe the current behaviour violates the
principle of least astonishment and, as you've
described, can lead to highly unexpected timing bugs.

gen:call() doesn't enable exit trapping under any
circumstances (nor does it link to the server),
so if the process is trapping exits, and is linked
to the server, it is certainly because someone else
made it so. It is then reasonable to expect that
some other code expects an EXIT message to arrive.

One of the main reasons why monitors were added in
the first place was the problem that link/unlink
and EXIT message handling can't be handled locally,
since no matter how many times you call link(),
there will only be one link, and the first call
to unlink removes that link. Furthermore, there
is only one EXIT message (except if link(DeadPid)
has been called one or more times), and the
handling of that message must be a process-global
matter.


BR,
Ulf W

> -----Original Message-----
> From: erlang-questions-bounces@erlang.org
> [mailto:erlang-questions-bounces@erlang.org] On Behalf Of Sean Hinde
> Sent: den 25 januari 2007 17:33
> To: Erlang Questions
> Subject: Re: [erlang-questions] Programming question
>
>
> On 25 Jan 2007, at 12:35, Richard Carlsson wrote:
>
> > Sean Hinde wrote:
> >>
> >> The problem as I see it is that the calling process only
> sometimes
> >> get its 'EXIT' message - it depends on context.
> >
> > If you have a library that uses the RPC model, as in the case of
> > 'gen_server:call(...)', it is probably a bad idea to try to
> solve the
> > problems with RPC that have been known for ages, such as
> "what do I do
> > if the server goes down", by adding some ad-hoc handling
> code to every
> > remote call. (It can and will be screwed up anyway.) I
> think that the
> > interface should be used as it was intended (treating
> exceptions due
> > to server-down as any other exception out from the call), and that
> > additional supervision should be placed somewhere else, outside the
> > main program logic.
> >
> > Sean is basically right here: he _ought_ to be able to use normal
> > links for this purpose (after all, links are the central built-in
> > "additional supervision" method in Erlang), regardless of
> whether the
> > implementation of gen_server:call() does things with links and
> > trapping of signals: that stuff should have been made
> transparent to
> > the user, but is obviously not. (One problem is that there
> can only be
> > a single link between two processes, so gen_server can't
> know whether
> > or not it should re-issue the caught signal to the caller.)
>
> Actually it can, because gen_server can rely solely on
> monitor for its own purposes. If it gets an 'EXIT' message
> then it can be certain that it is because the two processes
> have been explicitly linked.
>
> I would be happy to have a compatibility mode for dealing
> with old nodes, but I think the default behaviour should for
> gen_server to selectively receive its own 'DOWN' message, and
> leave the EXIT message on the queue.
>
>
> >
> > If this aspect of gen_server (and similar library
> functions) cannot be
> > fixed, e.g. by using monitors instead of links, then at a
> minimum it
> > should be documented that the functions will steal exit
> signals if you
> > try to link directly to the server.
>
> I agree with the documentation comment. It was extremely
> surprising the first time I saw this behaviour. It resulted
> in several outages of live systems where processes were not
> restarted simply because of when they died (not code written
> by me, so at least two folks have had this problem). There
> must be many other systems out there that are just waiting to
> suffer the same fate.
>
> >
> > Meanwhile, the fix I suggested previously should work fine: use an
> > intermediate process, whose signals the gen_server library does not
> > interfere with.
>
> To require a 3rd process between the two linked process just
> to propogate the EXIT seems like extreme overkill. In my
> current application the two process are dynamically created
> per call - this would add a 50% overhead to every request.
>
> I don't buy the backwards compatibility argument for this
> unintuitive and IMO buggy behaviour. If we look at the cases:
>
> 1. Two processes are not linked.
>
> Today - if the other process dies during the call then
> gen:call() just throws an exception.
> With my change - exactly the same
>
> 2. Two processes are linked, with the gen:call not wrapped in a catch
>
> Today - if the other process dies during the call it throws
> an exception and the local process dies With my change - same
> result, the 'EXIT' message arrives later after the caller died
>
> 3. Two processes are linked, gen:call wrapped in a catch,
> trapexit = true
>
> Today - if the other process dies during the call then an
> exception is caught. There is no 'EXIT' message, even though
> this has to be handled if the linked process dies at any other time.
> With my change - The same exception is raised from the call,
> but the existing 'EXIT' message handling will also be
> invoked. - To me this is a pure bug fix
>
> 4. Two processes are linked, gen:call wrapped in a catch,
> trapexit = false
>
> Today - Exception is raised as normal, and the calling
> process lives on.
> With proposed change: Exception is raised as normal but the
> calling process is killed later by the 'EXIT' signal.
>
> This last case could be seen as a backwards compatibility
> problem, but given that the called process can potentially
> die at any time outside the call, I would say that the
> gen_server behaviour is just hiding a latent bug in the
> original code, which is likely to happen at some point anyway.
>
> Worst case we could have a separate call defined with the new
> behaviour
>
> Sean
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
>

_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
View user's profile Send private message Visit poster's website
Guest
Posted: Thu Jan 25, 2007 6:35 pm Reply with quote
Guest
On 25 Jan 2007, at 17:23, Ulf Wiger ((TN/EAB)) wrote:

>
>> To require a 3rd process between the two linked process just
>> to propogate the EXIT seems like extreme overkill. In my
>> current application the two process are dynamically created
>> per call - this would add a 50% overhead to every request.
>
> To be fair, this would be 50% overhead on the cost of
> spawning processes, which is about 5-10 us/spawn.
> It is hardly noticeable in most cases.

OK, perhaps this was the worst reason I could choose to explain why
requiring an extra process is a bad idea. Others are obvious - added
complexity, more code that has nothing to do with the end user
requirements, potential for additional bugs, harder to understand etc
etc etc.

> I agree that gen_server shouldn't touch the EXIT
> messages. While changing this might cause some
> consternation among a few users with legacy code,
> I believe the current behaviour violates the
> principle of least astonishment and, as you've
> described, can lead to highly unexpected timing bugs.

Great! Now we must convince the OTP team..

Sean


>
> gen:call() doesn't enable exit trapping under any
> circumstances (nor does it link to the server),
> so if the process is trapping exits, and is linked
> to the server, it is certainly because someone else
> made it so. It is then reasonable to expect that
> some other code expects an EXIT message to arrive.
>
> One of the main reasons why monitors were added in
> the first place was the problem that link/unlink
> and EXIT message handling can't be handled locally,
> since no matter how many times you call link(),
> there will only be one link, and the first call
> to unlink removes that link. Furthermore, there
> is only one EXIT message (except if link(DeadPid)
> has been called one or more times), and the
> handling of that message must be a process-global
> matter.
>
>
> BR,
> Ulf W
>
>> -----Original Message-----
>> From: erlang-questions-bounces@erlang.org
>> [mailto:erlang-questions-bounces@erlang.org] On Behalf Of Sean Hinde
>> Sent: den 25 januari 2007 17:33
>> To: Erlang Questions
>> Subject: Re: [erlang-questions] Programming question
>>
>>
>> On 25 Jan 2007, at 12:35, Richard Carlsson wrote:
>>
>>> Sean Hinde wrote:
>>>>
>>>> The problem as I see it is that the calling process only
>> sometimes
>>>> get its 'EXIT' message - it depends on context.
>>>
>>> If you have a library that uses the RPC model, as in the case of
>>> 'gen_server:call(...)', it is probably a bad idea to try to
>> solve the
>>> problems with RPC that have been known for ages, such as
>> "what do I do
>>> if the server goes down", by adding some ad-hoc handling
>> code to every
>>> remote call. (It can and will be screwed up anyway.) I
>> think that the
>>> interface should be used as it was intended (treating
>> exceptions due
>>> to server-down as any other exception out from the call), and that
>>> additional supervision should be placed somewhere else, outside the
>>> main program logic.
>>>
>>> Sean is basically right here: he _ought_ to be able to use normal
>>> links for this purpose (after all, links are the central built-in
>>> "additional supervision" method in Erlang), regardless of
>> whether the
>>> implementation of gen_server:call() does things with links and
>>> trapping of signals: that stuff should have been made
>> transparent to
>>> the user, but is obviously not. (One problem is that there
>> can only be
>>> a single link between two processes, so gen_server can't
>> know whether
>>> or not it should re-issue the caught signal to the caller.)
>>
>> Actually it can, because gen_server can rely solely on
>> monitor for its own purposes. If it gets an 'EXIT' message
>> then it can be certain that it is because the two processes
>> have been explicitly linked.
>>
>> I would be happy to have a compatibility mode for dealing
>> with old nodes, but I think the default behaviour should for
>> gen_server to selectively receive its own 'DOWN' message, and
>> leave the EXIT message on the queue.
>>
>>
>>>
>>> If this aspect of gen_server (and similar library
>> functions) cannot be
>>> fixed, e.g. by using monitors instead of links, then at a
>> minimum it
>>> should be documented that the functions will steal exit
>> signals if you
>>> try to link directly to the server.
>>
>> I agree with the documentation comment. It was extremely
>> surprising the first time I saw this behaviour. It resulted
>> in several outages of live systems where processes were not
>> restarted simply because of when they died (not code written
>> by me, so at least two folks have had this problem). There
>> must be many other systems out there that are just waiting to
>> suffer the same fate.
>>
>>>
>>> Meanwhile, the fix I suggested previously should work fine: use an
>>> intermediate process, whose signals the gen_server library does not
>>> interfere with.
>>
>> To require a 3rd process between the two linked process just
>> to propogate the EXIT seems like extreme overkill. In my
>> current application the two process are dynamically created
>> per call - this would add a 50% overhead to every request.
>>
>> I don't buy the backwards compatibility argument for this
>> unintuitive and IMO buggy behaviour. If we look at the cases:
>>
>> 1. Two processes are not linked.
>>
>> Today - if the other process dies during the call then
>> gen:call() just throws an exception.
>> With my change - exactly the same
>>
>> 2. Two processes are linked, with the gen:call not wrapped in a catch
>>
>> Today - if the other process dies during the call it throws
>> an exception and the local process dies With my change - same
>> result, the 'EXIT' message arrives later after the caller died
>>
>> 3. Two processes are linked, gen:call wrapped in a catch,
>> trapexit = true
>>
>> Today - if the other process dies during the call then an
>> exception is caught. There is no 'EXIT' message, even though
>> this has to be handled if the linked process dies at any other time.
>> With my change - The same exception is raised from the call,
>> but the existing 'EXIT' message handling will also be
>> invoked. - To me this is a pure bug fix
>>
>> 4. Two processes are linked, gen:call wrapped in a catch,
>> trapexit = false
>>
>> Today - Exception is raised as normal, and the calling
>> process lives on.
>> With proposed change: Exception is raised as normal but the
>> calling process is killed later by the 'EXIT' signal.
>>
>> This last case could be seen as a backwards compatibility
>> problem, but given that the called process can potentially
>> die at any time outside the call, I would say that the
>> gen_server behaviour is just hiding a latent bug in the
>> original code, which is likely to happen at some point anyway.
>>
>> Worst case we could have a separate call defined with the new
>> behaviour
>>
>> Sean
>>
>>
>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@erlang.org
>> http://www.erlang.org/mailman/listinfo/erlang-questions
>>

_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
Guest
Posted: Fri Jan 26, 2007 8:10 am Reply with quote
Guest
Ulf Wiger (TN/EAB) wrote:
> I agree that gen_server shouldn't touch the EXIT
> messages. While changing this might cause some
> consternation among a few users with legacy code,
> I believe the current behaviour violates the
> principle of least astonishment and, as you've
> described, can lead to highly unexpected timing bugs.
>
> gen:call() doesn't enable exit trapping under any
> circumstances (nor does it link to the server),
> so if the process is trapping exits, and is linked
> to the server, it is certainly because someone else
> made it so. It is then reasonable to expect that
> some other code expects an EXIT message to arrive.

There is another issue with the catch sentence in the block that
handles call requests in gen_server.erl:


call(Name, Request) ->
case catch gen:call(Name, '$gen_call', Request) of
{ok,Res} ->
Res;
{'EXIT',Reason} ->
exit({Reason, {?MODULE, call, [Name, Request]}})
end.

call(Name, Request, Timeout) ->
case catch gen:call(Name, '$gen_call', Request, Timeout) of
{ok,Res} ->
Res;
{'EXIT',Reason} ->
exit({Reason, {?MODULE, call, [Name, Request, Timeout]}})
end.


That does not do well with the behaviour that a try-catch user
expects. An uncatched signal becomes a return term. So a gen_server with
the next code:


handle_call(trhow_it, _From, State) ->
throw(ouch),
{reply, ok, State};

handle_call(weird, _From, State) ->
throw({reply, ok, State}),
{stop, ok, State};

handle_call(expected, _From, State) ->
erlang:error({nocatch, ouch}),
{reply, ok, State}.


Behaves as funny as:


16> gen_server_throw:start_link().
{ok,<0.78.0>}
17> gen_server:call(test, weird).
ok
18> gen_server:call(test, trhow_it).

=ERROR REPORT==== 26-Jan-2007::08:47:46 ===
** Generic server test terminating
** Last message in was trhow_it
** When Server state == {}
** Reason for termination ==
** {bad_return_value,ouch}
** exited: {bad_return_value,ouch} **
19> gen_server_throw:start_link().
ok,<0.83.0>}
20> gen_server:call(test, expected).

=ERROR REPORT==== 26-Jan-2007::08:48:07 ===
** Generic server test terminating
** Last message in was expected
** When Server state == {}
** Reason for termination ==
** {{nocatch,ouch},
[{gen_server_throw,handle_call,3},
{gen_server,handle_msg,6},
{proc_lib,init_p,5}]}
** exited: {{nocatch,ouch},
[{gen_server_throw,handle_call,3},
{gen_server,handle_msg,6},
{proc_lib,init_p,5}]} **


- I would expect that 'throw_it' caused an exception similar
to 'expected' (with the right stack trace)
- I would expect that 'weird' caused a similar exception too, but it
does not even crash the server.

I did not find any mention about throw issues in the manual either.

Regards
--
Samuel
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
uffe
Posted: Fri Jan 26, 2007 8:33 am Reply with quote
User Joined: 02 Mar 2005 Posts: 365 Location: Sweden
Den 2007-01-26 09:01:22 skrev Samuel Rivas <samuelrivas@udc.es>:

> handle_call(trhow_it, _From, State) ->
> throw(ouch),
> {reply, ok, State};
> handle_call(weird, _From, State) ->
> throw({reply, ok, State}),
> {stop, ok, State};
> handle_call(expected, _From, State) ->
> erlang:error({nocatch, ouch}),
> {reply, ok, State}.

[...]

> - I would expect that 'throw_it' caused an exception similar
> to 'expected' (with the right stack trace)

The exception in this case is raised by the gen_server module,
which expects a return value from Mod:handle_call/3 to be
{reply,Rep,S1} | {noreply,S1} | {stop,Reason,S1}
| {stop,Rep,Reason,S1}

'ouch' doesn't qualify as a valid return value.

In the case of 'expected', your code raises an exception,
which is caught by the gen_server module, which adds some
info (e.g. last message) and then exits (I'm not looking
at the code - can't remember if it calls exit/1 or error/1.)


> - I would expect that 'weird' caused a similar exception too,
> but it does not even crash the server.

...because gen_server uses an old-style catch, and therefore
cannot tell the difference between your thrown value and a
normal (and legal) return value.


--
Ulf Wiger
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
View user's profile Send private message Visit poster's website
Guest
Posted: Fri Jan 26, 2007 8:43 am Reply with quote
Guest
Ulf Wiger wrote:
> > - I would expect that 'throw_it' caused an exception similar
> > to 'expected' (with the right stack trace)
>
> The exception in this case is raised by the gen_server module,
> which expects a return value from Mod:handle_call/3 to be
> {reply,Rep,S1} | {noreply,S1} | {stop,Reason,S1}
> | {stop,Rep,Reason,S1}
>
> 'ouch' doesn't qualify as a valid return value.
>
> In the case of 'expected', your code raises an exception,
> which is caught by the gen_server module, which adds some
> info (e.g. last message) and then exits (I'm not looking
> at the code - can't remember if it calls exit/1 or error/1.)
>
>
> > - I would expect that 'weird' caused a similar exception too,
> > but it does not even crash the server.
>
> ...because gen_server uses an old-style catch, and therefore
> cannot tell the difference between your thrown value and a
> normal (and legal) return value.

I knew it, my point is that you have to read the source. Otherwise the
results are astonishing.

Regards
--
Samuel
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
uwiger
Posted: Fri Jan 26, 2007 9:14 am Reply with quote
User Joined: 03 Jul 2006 Posts: 604 Location: Sweden
Yes, this is one of the problems with the old
catch/throw, which were eminently documented in
Richard Carlsson's et al paper on Erlang's Exception Handling Revisited

http://www.erlang.se/workshop/2004/exception.pdf

BR,
Ulf W

> -----Original Message-----
> From: erlang-questions-bounces@erlang.org
> [mailto:erlang-questions-bounces@erlang.org] On Behalf Of Samuel Rivas
> Sent: den 26 januari 2007 09:39
> To: erlang-questions@erlang.org
> Subject: Re: [erlang-questions] Programming question
>
> Ulf Wiger wrote:
> > > - I would expect that 'throw_it' caused an exception similar
> > > to 'expected' (with the right stack trace)
> >
> > The exception in this case is raised by the gen_server
> module, which
> > expects a return value from Mod:handle_call/3 to be
> {reply,Rep,S1} |
> > {noreply,S1} | {stop,Reason,S1}
> > | {stop,Rep,Reason,S1}
> >
> > 'ouch' doesn't qualify as a valid return value.
> >
> > In the case of 'expected', your code raises an exception, which is
> > caught by the gen_server module, which adds some info (e.g. last
> > message) and then exits (I'm not looking at the code -
> can't remember
> > if it calls exit/1 or error/1.)
> >
> >
> > > - I would expect that 'weird' caused a similar exception too,
> > > but it does not even crash the server.
> >
> > ...because gen_server uses an old-style catch, and therefore cannot
> > tell the difference between your thrown value and a normal
> (and legal)
> > return value.
>
> I knew it, my point is that you have to read the source.
> Otherwise the results are astonishing.
>
> Regards
> --
> Samuel
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
>

_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
View user's profile Send private message Visit poster's website
Guest
Posted: Fri Jan 26, 2007 10:55 am Reply with quote
Guest
Ulf Wiger (TN/EAB) wrote:
> Yes, this is one of the problems with the old
> catch/throw, which were eminently documented in
> Richard Carlsson's et al paper on Erlang's Exception Handling Revisited

Ya. I started using try/catch some time ago, but I usually stumble
upon OTP, Either because of the famous "tagged returns VS exceptions" or
because of gotchas with the standard behaviours. We have developed a
custom supervisor and a library wrapping gen_server usage to avoid some
issues. I guess it is difficult to fix preserving backwards
compatibility, maybe it is worth developing a second generation of
behaviours ...

Regards
--
Samuel
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
Thomas Lindgren
Posted: Fri Jan 26, 2007 11:37 am Reply with quote
User Joined: 09 Mar 2005 Posts: 284
--- Samuel Rivas <samuelrivas@udc.es> wrote:
> I guess it is difficult to fix preserving
> backwards
> compatibility, maybe it is worth developing a second
> generation of behaviours ...

While they don't do it in order to use try/catch, it
has been my experience that veteran erlang companies
(or companies with erlang veterans) remarkably often
develop and use their own SASL-equivalents.

Best,
Thomas




____________________________________________________________________________________
Now that's room service! Choose from over 150,000 hotels
in 45,000 destinations on Yahoo! Travel to find your fit.
http://farechase.yahoo.com/promo-generic-14795097
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
View user's profile Send private message
wuji
Posted: Wed Aug 22, 2012 8:02 am Reply with quote
User Joined: 10 Aug 2012 Posts: 654
a link to go to Netflix, you would wind up up jordan 6 up at "BudgetMatch," according to the FBI. The practice is
"click hijacking."Once the FBI got around to fixing the problem problem [h4]cheap jordans[/h4] problem in 2011, it realized it couldn't simply shut down
rogue servers because infected computers would be left without a a cheap replica *beep* a functioning DNS, leaving them virtually Internet-less. So it set
temporary servers to give malware-infected Internet users time to fix fix jordan 6 fix their computers.And time runs out on Monday, July 9.(There
a planned attack this Monday that will shut down the the imitation designer *beep* the Internet; those whose computers are already infected will lose
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 2 of 2
Goto page Previous  1, 2
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum