-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
errors are not surfaced unless channel is immediately collect
ed
#4
Comments
I think this might be a race condition with a buffered channel. bound task failure will be propagated to any task waiting on the channel, but if it's closed by task completion before the buffer is full, then there's no waiting. Here's an even more MWE of this behavior: julia> c = Channel(1) do ch
put!(ch, nothing)
error("aHHHH")
end
Channel{Any}(1) (closed)
julia> collect(c)
1-element Vector{Any}:
nothing
julia> collect(Channel(1) do ch
put!(ch, nothing)
error("aHHHH")
end)
ERROR: TaskFailedException
Stacktrace:
[1] try_yieldto(undo::typeof(Base.ensure_rescheduled))
@ Base ./task.jl:871
[2] wait()
@ Base ./task.jl:931
[3] wait(c::Base.GenericCondition{ReentrantLock})
@ Base ./condition.jl:124
[4] take_buffered(c::Channel{Any})
@ Base ./channels.jl:416
[5] take!
@ ./channels.jl:410 [inlined]
[6] iterate(c::Channel{Any}, state::Nothing)
@ Base ./channels.jl:498
[7] _collect(cont::UnitRange{Int64}, itr::Channel{Any}, #unused#::Base.HasEltype, isz::Base.SizeUnknown)
@ Base ./array.jl:725
[8] collect(itr::Channel{Any})
@ Base ./array.jl:712
[9] top-level scope
@ REPL[20]:1
nested task error: aHHHH
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] (::var"#9#10")(ch::Channel{Any})
@ Main ./REPL[20]:3
[3] (::Base.var"#591#592"{var"#9#10", Channel{Any}})()
@ Base ./channels.jl:134
julia> c = Channel(0) do ch
put!(ch, nothing)
error("aHHHH")
end
Channel{Any}(0) (1 item available)
julia> collect(c)
ERROR: TaskFailedException
Stacktrace:
[1] try_yieldto(undo::typeof(Base.ensure_rescheduled))
@ Base ./task.jl:871
[2] wait()
p @ Base ./task.jl:931
[3] wait(c::Base.GenericCondition{ReentrantLock})
@ Base ./condition.jl:124
[4] take_unbuffered(c::Channel{Any})
@ Base ./channels.jl:433
[5] take!
@ ./channels.jl:410 [inlined]
[6] iterate(c::Channel{Any}, state::Nothing)
@ Base ./channels.jl:498
[7] _collect(cont::UnitRange{Int64}, itr::Channel{Any}, #unused#::Base.HasEltype, isz::Base.SizeUnknown)
@ Base ./array.jl:725
[8] collect(itr::Channel{Any})
@ Base ./array.jl:712
[9] top-level scope
@ REPL[22]:1
nested task error: aHHHH
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] (::var"#11#12")(ch::Channel{Any})
@ Main ./REPL[21]:3
[3] (::Base.var"#591#592"{var"#11#12", Channel{Any}})()
@ Base ./channels.jl:134 |
okay the underlying issue here is this: when we iterate a channel, it checks if the channel is open or ready; if it's neither of these, it returns Another possibility would be to have a "sync" mode which will immediately collect/wait on the channel adn return that value. then we're more or less guaranteed to be waiting when the error is reported... |
A final possibility would be to use an unbuffered channel so that all iteration calls will involve a wait; that seems the safest to me actually since I don't think there's a huge benefit to using a buffered channel if there's nothing async happening on the consumer end. we could change the default for channel capacity to be 0 and allow users to set it higher if they need buffering for some reason. |
This is probably out of scope for MockTableGenerators, but I think a useful primitive would be an object that wraps a channel but adds nicer semantics on top. Ideally it could be close to drop-in replacement for a channel, but it would store the bound task (using |
Yeah I dunno, it's tricky because there's two things getting mixed in here: teh channel and the (bound) task. We could maybe create a |
Fixed by JuliaLang/julia#52981? |
To obtain similar behaviour as the fix, we could wrap the channel in an iterator that passes through try
wait(channel)
catch ex
ex isa InvalidStateException || rethrow(ex)
end |
MWE:
The text was updated successfully, but these errors were encountered: