Skip to content

Commit af407a3

Browse files
committed
ThunkFailedException: Scrub out Thunk
1 parent 731fd7f commit af407a3

File tree

2 files changed

+52
-27
lines changed

2 files changed

+52
-27
lines changed

src/thunk.jl

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -194,33 +194,53 @@ unwrap_weak_checked(t) = t
194194
Base.show(io::IO, t::WeakThunk) = (print(io, "~"); Base.show(io, t.x.value))
195195
Base.convert(::Type{WeakThunk}, t::Thunk) = WeakThunk(t)
196196

197+
"A summary of the data contained in a Thunk, which can be safely serialized."
198+
struct ThunkSummary
199+
id::Int
200+
f
201+
inputs::Vector{Pair{Union{Symbol,Nothing},Any}}
202+
end
203+
inputs(t::ThunkSummary) = t.inputs
204+
Base.show(io::IO, t::ThunkSummary) = show_thunk(io, t)
205+
function Base.convert(::Type{ThunkSummary}, t::Thunk)
206+
return ThunkSummary(t.id,
207+
t.f,
208+
map(pos_inp->istask(pos_inp[2]) ? pos_inp[1]=>convert(ThunkSummary, pos_inp[2]) : pos_inp,
209+
t.inputs))
210+
end
211+
function Base.convert(::Type{ThunkSummary}, t::WeakThunk)
212+
t = unwrap_weak(t)
213+
if t !== nothing
214+
t = convert(ThunkSummary, t)
215+
end
216+
return t
217+
end
218+
197219
struct ThunkFailedException{E<:Exception} <: Exception
198-
thunk::WeakThunk
199-
origin::WeakThunk
220+
thunk::ThunkSummary
221+
origin::ThunkSummary
200222
ex::E
201223
end
202224
ThunkFailedException(thunk, origin, ex::E) where E =
203-
ThunkFailedException{E}(convert(WeakThunk, thunk), convert(WeakThunk, origin), ex)
225+
ThunkFailedException{E}(convert(ThunkSummary, thunk),
226+
convert(ThunkSummary, origin),
227+
ex)
204228
function Base.showerror(io::IO, ex::ThunkFailedException)
205-
t = unwrap_weak(ex.thunk)
229+
t = ex.thunk
206230

207231
# Find root-cause thunk
208232
last_tfex = ex
209-
failed_tasks = Union{Thunk,Nothing}[]
210-
while last_tfex.ex isa ThunkFailedException && unwrap_weak(last_tfex.ex.origin) !== nothing
211-
push!(failed_tasks, unwrap_weak(last_tfex.thunk))
233+
failed_tasks = Union{ThunkSummary,Nothing}[]
234+
while last_tfex.ex isa ThunkFailedException
235+
push!(failed_tasks, last_tfex.thunk)
212236
last_tfex = last_tfex.ex
213237
end
214-
o = unwrap_weak(last_tfex.origin)
238+
o = last_tfex.origin
215239
root_ex = last_tfex.ex
216240

217241
function thunk_string(t)
218-
if t === nothing
219-
return "Thunk(?)"
220-
end
221242
Tinputs = Any[]
222243
for (_, input) in t.inputs
223-
input = unwrap_weak(input)
224244
if istask(input)
225245
push!(Tinputs, "Thunk(id=$(input.id))")
226246
else
@@ -236,13 +256,11 @@ function Base.showerror(io::IO, ex::ThunkFailedException)
236256
end
237257
t_str = thunk_string(t)
238258
o_str = thunk_string(o)
239-
t_id = t !== nothing ? t.id : '?'
240-
o_id = o !== nothing ? o.id : '?'
241259
println(io, "ThunkFailedException:")
242260
println(io, " Root Exception Type: $(typeof(root_ex))")
243261
println(io, " Root Exception:")
244262
Base.showerror(io, root_ex); println(io)
245-
if t !== o
263+
if t.id !== o.id
246264
println(io, " Root Thunk: $o_str")
247265
if length(failed_tasks) <= 4
248266
for i in failed_tasks
@@ -419,36 +437,36 @@ cache_result!(t::Thunk) = (t.cache=true; t)
419437
Base.hash(x::Thunk, h::UInt) = hash(x.id, hash(h, 0x7ad3bac49089a05f % UInt))
420438
Base.isequal(x::Thunk, y::Thunk) = x.id==y.id
421439

422-
function Base.show(io::IO, z::Thunk)
440+
function show_thunk(io::IO, t)
423441
lvl = get(io, :lazy_level, 2)
424-
f = if z.f isa Chunk
425-
Tf = z.f.chunktype
442+
f = if t.f isa Chunk
443+
Tf = t.f.chunktype
426444
if isdefined(Tf, :instance)
427445
Tf.instance
428446
else
429447
"instance of $Tf"
430448
end
431449
else
432-
z.f
450+
t.f
433451
end
434-
print(io, "Thunk[$(z.id)]($f, ")
452+
print(io, "Thunk[$(t.id)]($f, ")
435453
if lvl > 0
436-
inputs = Any[]
437-
for (pos, input) in z.inputs
454+
t_inputs = Any[]
455+
for (pos, input) in inputs(t)
438456
if pos === nothing
439-
push!(inputs, input)
457+
push!(t_inputs, input)
440458
else
441-
push!(inputs, pos => input)
459+
push!(t_inputs, pos => input)
442460
end
443461
end
444-
show(IOContext(io, :lazy_level => lvl-1), inputs)
462+
show(IOContext(io, :lazy_level => lvl-1), t_inputs)
445463
else
446464
print(io, "...")
447465
end
448466
print(io, ")")
449467
end
450-
451-
Base.summary(z::Thunk) = repr(z)
468+
Base.show(io::IO, t::Thunk) = show_thunk(io, t)
469+
Base.summary(t::Thunk) = repr(t)
452470

453471
inputs(x::Thunk) = x.inputs
454472
inputs(x) = ()

test/thunk.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ end
181181

182182
# Mild stress-test
183183
@test dynamic_fib(10) == 55
184+
185+
# Errors on remote are correctly scrubbed (#430)
186+
t2 = remotecall_fetch(2) do
187+
t1 = Dagger.@spawn 1+"fail"
188+
Dagger.@spawn t1+1
189+
end
190+
@test_throws_unwrap Dagger.ThunkFailedException fetch(t2)
184191
end
185192
@testset "undefined function" begin
186193
# Issues #254, #255

0 commit comments

Comments
 (0)