Skip to content

Commit 70018be

Browse files
amitmurthytkelman
authored andcommitted
propagate errors on wait(::RemoteRef) and remotecall_wait
(cherry picked from commit a2e7cf4) ref #13744
1 parent 4b5626d commit 70018be

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

base/multi.jl

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,9 @@ function remotecall_wait(w::Worker, f, args...)
744744
rv.waitingfor = w.id
745745
rr = RemoteRef(w)
746746
send_msg(w, CallWaitMsg(f, args, rr2id(rr), prid))
747-
wait(rv)
747+
v = fetch(rv.c)
748748
delete!(PGRP.refs, prid)
749+
isa(v, RemoteException) && throw(v)
749750
rr
750751
end
751752

@@ -778,8 +779,18 @@ function call_on_owner(f, rr::RemoteRef, args...)
778779
end
779780
end
780781

781-
wait_ref(rid, args...) = (wait(lookup_ref(rid).c, args...); nothing)
782-
wait(r::RemoteRef, args...) = (call_on_owner(wait_ref, r, args...); r)
782+
function wait_ref(rid, callee, args...)
783+
v = fetch_ref(rid, args...)
784+
if isa(v, RemoteException)
785+
if myid() == callee
786+
throw(v)
787+
else
788+
return v
789+
end
790+
end
791+
nothing
792+
end
793+
wait(r::RemoteRef, args...) = (call_on_owner(wait_ref, r, myid(), args...); r)
783794

784795
fetch_ref(rid, args...) = fetch(lookup_ref(rid).c, args...)
785796
fetch(r::RemoteRef, args...) = call_on_owner(fetch_ref, r, args...)
@@ -791,19 +802,23 @@ put_ref(rid, args...) = put!(lookup_ref(rid), args...)
791802
put!(rr::RemoteRef, args...) = (call_on_owner(put_ref, rr, args...); rr)
792803

793804
take!(rv::RemoteValue, args...) = take!(rv.c, args...)
794-
take_ref(rid, args...) = take!(lookup_ref(rid), args...)
795-
take!(rr::RemoteRef, args...) = call_on_owner(take_ref, rr, args...)
805+
function take_ref(rid, callee, args...)
806+
v=take!(lookup_ref(rid), args...)
807+
isa(v, RemoteException) && (myid() == callee) && throw(v)
808+
v
809+
end
810+
take!(rr::RemoteRef, args...) = call_on_owner(take_ref, rr, myid(), args...)
796811

797812
close_ref(rid) = (close(lookup_ref(rid).c); nothing)
798813
close(rr::RemoteRef) = call_on_owner(close_ref, rr)
799814

800815

801816
function deliver_result(sock::IO, msg, oid, value)
802817
#print("$(myid()) sending result $oid\n")
803-
if is(msg,:call_fetch)
818+
if is(msg,:call_fetch) || isa(value, RemoteException)
804819
val = value
805820
else
806-
val = oid
821+
val = :OK
807822
end
808823
try
809824
send_msg_now(sock, ResultMsg(oid, val))
@@ -898,7 +913,7 @@ end
898913
function handle_msg(msg::CallWaitMsg, r_stream, w_stream)
899914
@schedule begin
900915
rv = schedule_call(msg.response_oid, ()->msg.f(msg.args...))
901-
deliver_result(w_stream, :call_wait, msg.notify_oid, wait(rv))
916+
deliver_result(w_stream, :call_wait, msg.notify_oid, fetch(rv.c))
902917
end
903918
end
904919

test/parallel.jl

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -377,14 +377,24 @@ catch ex
377377
@test collect(1:5) == sort(map(x->parse(Int, x), errors))
378378
end
379379

380-
try
381-
remotecall_fetch(id_other, ()->throw(ErrorException("foobar")))
382-
error("unexpected")
383-
catch ex
384-
@test typeof(ex) == RemoteException
385-
@test typeof(ex.captured) == CapturedException
386-
@test typeof(ex.captured.ex) == ErrorException
387-
@test ex.captured.ex.msg == "foobar"
380+
macro test_remoteexception_thrown(expr)
381+
quote
382+
try
383+
$(esc(expr))
384+
error("unexpected")
385+
catch ex
386+
@test typeof(ex) == RemoteException
387+
@test typeof(ex.captured) == CapturedException
388+
@test typeof(ex.captured.ex) == ErrorException
389+
@test ex.captured.ex.msg == "foobar"
390+
end
391+
end
392+
end
393+
394+
for id in [id_other, id_me]
395+
@test_remoteexception_thrown remotecall_fetch(id, ()->throw(ErrorException("foobar")))
396+
@test_remoteexception_thrown remotecall_wait(id, ()->throw(ErrorException("foobar")))
397+
@test_remoteexception_thrown wait(remotecall(id, ()->throw(ErrorException("foobar"))))
388398
end
389399

390400
# The below block of tests are usually run only on local development systems, since:

0 commit comments

Comments
 (0)