rpc:call/4

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

rpc:call/4

Jayson Vantuyl-2
I've encountered unexpected behavior when doing rpc:call/4 to a remote node and the remote code has an exception.

The "error case" seems to be {badrpc,Reason}, with reason completely unspecified.  Oddly, I get the following behavior:

erlang:exit(X) gives {badrpc, {'EXIT',X}.
erlang:raise(X) gives {badrpc, {'EXIT',X,StackTrace}.
erlang:throw(X) gives X.

The first two are pretty reasonable.  The third one is a bit odd.

In a number of places, the rpc:call infrastructure seems to use the archaic:

> case catch .... of ... end.

In modern code, I would assume this would be the more expressive:

> try ... of ... catch ... end.

What is the expected behavior (the docs are a bit vague)?

--
Jayson Vantuyl
[hidden email]


________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:[hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: rpc:call/4

bile
May be an oversight or a relic. It's due to rpc:handle_call_call doing
a catch apply. Since catch throw gives back whatever was thrown and not
{'EXIT',_} all it can do is pass it back as a normal result.

While it'd be nice in this case to use the newer try catch behavior it'd
not be backward compatible. Though it'd probably lead some to find that
their RPCs had been failing.

And if it were changed... what would the first element of the tuple be?
'EXIT' like exit and error or something like 'THROW'. It'd be nice if
it were 'EXIT', 'ERROR', and 'THROW'. That's even more incompatible
however.

On Thu, 18 Feb 2010 00:38:34 -0800
Jayson Vantuyl <[hidden email]> wrote:

> I've encountered unexpected behavior when doing rpc:call/4 to a
> remote node and the remote code has an exception.
>
> The "error case" seems to be {badrpc,Reason}, with reason completely
> unspecified.  Oddly, I get the following behavior:
>
> erlang:exit(X) gives {badrpc, {'EXIT',X}.
> erlang:raise(X) gives {badrpc, {'EXIT',X,StackTrace}.
> erlang:throw(X) gives X.
>
> The first two are pretty reasonable.  The third one is a bit odd.
>
> In a number of places, the rpc:call infrastructure seems to use the
> archaic:
>
> > case catch .... of ... end.
>
> In modern code, I would assume this would be the more expressive:
>
> > try ... of ... catch ... end.
>
> What is the expected behavior (the docs are a bit vague)?
>


________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:[hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: rpc:call/4

Vinayak Pawar
In reply to this post by Jayson Vantuyl-2
erlang:throw is mainly intended for doing non-local returns from function
instead of error handling. Hence that bit odd rpc:call behaviour?

Regards,
Vinayak

On Thu, Feb 18, 2010 at 2:08 PM, Jayson Vantuyl <[hidden email]> wrote:

> I've encountered unexpected behavior when doing rpc:call/4 to a remote node
> and the remote code has an exception.
>
> The "error case" seems to be {badrpc,Reason}, with reason completely
> unspecified.  Oddly, I get the following behavior:
>
> erlang:exit(X) gives {badrpc, {'EXIT',X}.
> erlang:raise(X) gives {badrpc, {'EXIT',X,StackTrace}.
> erlang:throw(X) gives X.
>
> The first two are pretty reasonable.  The third one is a bit odd.
>
> In a number of places, the rpc:call infrastructure seems to use the
> archaic:
>
> > case catch .... of ... end.
>
> In modern code, I would assume this would be the more expressive:
>
> > try ... of ... catch ... end.
>
> What is the expected behavior (the docs are a bit vague)?
>
> --
> Jayson Vantuyl
> [hidden email]
>
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:[hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: rpc:call/4

Jayson Vantuyl-2
Is this true?

I mean, exit / error / throw has always been a very weird division to me.  I can't say that I completely understand what the breakdown is, although I usually know which one I should use.  Generally, throw is used as a form of high-level flow control, exit is for when you explicitly intend to exit a process, and error is for when you have an error (which defaults to terminating the process, but can be caught if it's expected).

I can't imagine that the case catch is the right way to do it.  The behavior is undocumented, and I really can't imagine that we should rely on it.

As much as I love stability, I think it's safe to say that it's reasonable to expect people to update their code to run on updated versions of Erlang.  This is why we deprecate things and have release notes.  I can't imagine this to be any more disruptive than, say, deprecating the re module.

As a member of the Erlang community, I really don't think we should go this direction:  http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4273532

That said, I'd love to hear from someone at Ericsson whether they think this is a bug.

From the documentation, I think so.  Intuitively I also feel that it's bad because it means that you can't distinguish between a throw and a return value if you use rpc:call.  This is really a bad design bug in any rpc mechanism that wants to be event remotely transparent.  I understand that when rpc was written, this was the only tool available.  Times have changed.

Is it worth my time to submit a patch?  For that matter, I'd be interested in just eliminating this idiom from the whole of OTP.  I don't think it's ever justified anymore.  Of course, a crude check shows 2082 occurrences.  That would be a pretty big patch.  Then again, 370 of them are in tests, so that might be a good place to start...

On Feb 19, 2010, at 1:26 AM, Vinayak Pawar wrote:

> erlang:throw is mainly intended for doing non-local returns from function
> instead of error handling. Hence that bit odd rpc:call behaviour?
>
> Regards,
> Vinayak
>
> On Thu, Feb 18, 2010 at 2:08 PM, Jayson Vantuyl <[hidden email]> wrote:
>
>> I've encountered unexpected behavior when doing rpc:call/4 to a remote node
>> and the remote code has an exception.
>>
>> The "error case" seems to be {badrpc,Reason}, with reason completely
>> unspecified.  Oddly, I get the following behavior:
>>
>> erlang:exit(X) gives {badrpc, {'EXIT',X}.
>> erlang:raise(X) gives {badrpc, {'EXIT',X,StackTrace}.
>> erlang:throw(X) gives X.
>>
>> The first two are pretty reasonable.  The third one is a bit odd.
>>
>> In a number of places, the rpc:call infrastructure seems to use the
>> archaic:
>>
>>> case catch .... of ... end.
>>
>> In modern code, I would assume this would be the more expressive:
>>
>>> try ... of ... catch ... end.
>>
>> What is the expected behavior (the docs are a bit vague)?
>>
>> --
>> Jayson Vantuyl
>> [hidden email]
>>
>>
>> ________________________________________________________________
>> erlang-questions (at) erlang.org mailing list.
>> See http://www.erlang.org/faq.html
>> To unsubscribe; mailto:[hidden email]
>>
>>

--
Jayson Vantuyl
[hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: rpc:call/4

Björn Gustavsson
On Fri, Feb 19, 2010 at 11:09 AM, Jayson Vantuyl <[hidden email]> wrote:

> Is it worth my time to submit a patch?

I would say yes, and good time would be now so that it has a chance
to be included in R14.

But we can't guarantee that we will include any patch until we have seen
it. We will need to evaluate whether there are backward compatibility issues
or other problems.

>For that matter, I'd be interested in just eliminating this idiom from the whole of OTP.
> I don't think it's ever justified anymore.  Of course, a crude check shows 2082 occurrences.  That would be a pretty big patch.  Then again, 370 of them are in tests, so that might be a good place to start...

For that kind of clean-up, I suggest that you have at least one commit
per application,
and probably also separate commits for test cases and changes in applications.
For applications, it could further help to separate internal uses of
of old-style "catch"
inside modules and other uses that may be noticeable by outside callers.

The purpose of all this is to help us (and everyone else who is interested) to
review the changes, and to allow us include the safe changes first before all
other changes have been cleared.

And good commit messages, that explain why the change should be included
always helps.

--
Björn Gustavsson, Erlang/OTP, Ericsson AB

________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:[hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: rpc:call/4

Robert Virding
In reply to this post by Jayson Vantuyl-2
On 19 February 2010 11:09, Jayson Vantuyl <[hidden email]> wrote:
> Is this true?
>
> I mean, exit / error / throw has always been a very weird division to me.  I can't say that I completely understand what the breakdown is, although I usually know which one I should use.  Generally, throw is used as a form of high-level flow control, exit is for when you explicitly intend to exit a process, and error is for when you have an error (which defaults to terminating the process, but can be caught if it's expected).

This is the generally accepted way of using them and I feel a good way
of indicating what you mean. Throw is for non-local returns.

About exit, which has no stacktrace, and error, which does.
Originally, there was only exit without the stacktrace and at that
time internal errors did not generate stacktraces. Then internal
errors got stacktraces (a Big Win) but exit still didn't. Then later
instead of changing exit to have stacktraces error was added. This, I
feel, was a bad choice. So now there were two different ways of
signaling a desire to exit/error with basically exactly the same
semantics.

Catch is older than try, from the time there was only exit and throw.
We decided that it would both catch both exits and non-local returns
(throw) and it would pass thrown values through unmarked and wrap an
exit value with {'EXIT',...}. It is a feature that you can fake exit
values, but as it very easy to program around this if you want to be
safe we never felt that this was a problem.

When try came along the separation into 3 different classes was
perpetuated. Unfortunately being able to catch throws, while being
very practical, I feel confused the issue of when to use what by
equating a throw with exit/error. Erlang:raise/3 adds to this
confusion because with it you can "raise" a throw which sounds strange
if you mean it be a non-local return.

> I can't imagine that the case catch is the right way to do it.  The behavior is undocumented, and I really can't imagine that we should rely on it.

As the behaviour of catch is documented I assume you mean rpc here.

Robert

________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:[hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: rpc:call/4

Jayson Vantuyl-2
In reply to this post by Björn Gustavsson
I'll try to have a patch for the initial case (rpc:call/4) today.

Thanks,

On Feb 19, 2010, at 4:10 AM, Björn Gustavsson wrote:

> On Fri, Feb 19, 2010 at 11:09 AM, Jayson Vantuyl <[hidden email]> wrote:
>
>> Is it worth my time to submit a patch?
>
> I would say yes, and good time would be now so that it has a chance
> to be included in R14.
>
> But we can't guarantee that we will include any patch until we have seen
> it. We will need to evaluate whether there are backward compatibility issues
> or other problems.
>
>> For that matter, I'd be interested in just eliminating this idiom from the whole of OTP.
>> I don't think it's ever justified anymore.  Of course, a crude check shows 2082 occurrences.  That would be a pretty big patch.  Then again, 370 of them are in tests, so that might be a good place to start...
>
> For that kind of clean-up, I suggest that you have at least one commit
> per application,
> and probably also separate commits for test cases and changes in applications.
> For applications, it could further help to separate internal uses of
> of old-style "catch"
> inside modules and other uses that may be noticeable by outside callers.
>
> The purpose of all this is to help us (and everyone else who is interested) to
> review the changes, and to allow us include the safe changes first before all
> other changes have been cleared.
>
> And good commit messages, that explain why the change should be included
> always helps.
>
> --
> Björn Gustavsson, Erlang/OTP, Ericsson AB

--
Jayson Vantuyl
[hidden email]


________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:[hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: rpc:call/4

Jayson Vantuyl-2
In reply to this post by Robert Virding
> As the behaviour of catch is documented I assume you mean rpc here.
Yes, rpc.

--
Jayson Vantuyl
[hidden email]


________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:[hidden email]