Skip to content
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

document isopen(::Channel) #56376

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Conversation

mrufsvold
Copy link

@mrufsvold mrufsvold commented Oct 29, 2024

This PR has two purposes --

  1. Add some documentation for public API
  2. Add a small note about a footgun I've hit a few times: !isopen(ch) does not mean that you are "done" with the channel because buffered channels can still have items left in them that need to be taken.

@LilithHafner LilithHafner added docs This change adds or pertains to documentation multithreading Base.Threads and related functionality labels Oct 29, 2024
Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the unbuffered channel example here is misleading, since even unbuffered channels can have concurrent blocked put! operations that mean there is isready data after !isopen

base/channels.jl Outdated
Comment on lines 240 to 251

Unbuffered channel:
```jldoctest
julia> c = Channel{Int}()

julia> isopen(c)
true

julia> close(c)

julia> isopen(c)
false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Unbuffered channel:
```jldoctest
julia> c = Channel{Int}()
julia> isopen(c)
true
julia> close(c)
julia> isopen(c)
false

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really? I thought, once an unbuffered channel is closed, all concurrent put!s error?

julia> ch = Channel()
Channel{Any}(0) (empty)

julia> t = @async put!(ch, 1)
Task (runnable) @0x000002028d9f1f10

julia> isready(ch)
true

julia> close(ch)

julia> isopen(ch)
false

julia> isready(ch)
false

julia> fetch(t)
ERROR: TaskFailedException
Stacktrace:
 [1] wait
   @ .\task.jl:359 [inlined]
 [2] fetch(t::Task)
   @ Base .\task.jl:379
 [3] top-level scope
   @ REPL[20]:1

    nested task error: InvalidStateException: Channel is closed.
    Stacktrace:
     [1] try_yieldto(undo::typeof(Base.ensure_rescheduled))
       @ Base .\task.jl:945
     [2] wait()
       @ Base .\task.jl:1009
     [3] wait(c::Base.GenericCondition{ReentrantLock}; first::Bool)
       @ Base .\condition.jl:130
     [4] wait
       @ .\condition.jl:125 [inlined]
     [5] put_unbuffered(c::Channel{Any}, v::Int64)
       @ Base .\channels.jl:387
     [6] put!(c::Channel{Any}, v::Int64)
       @ Base .\channels.jl:342
     [7] (::var"#17#18")()
       @ Main .\REPL[15]:1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay, I didn't know that. I guess that makes sense though

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I keeping hitting this issue. Since the behavior of unbuffered and buffered channels is subtly different, I'll add a buffer to a channel and introduce silent bugs elsewhere! Thank you for the review!

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you fix the couple of doctest failures and then this can merge

base/channels.jl Outdated

Unbuffered channel:
```jldoctest
julia> c = Channel{Int}()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
julia> c = Channel{Int}()
julia> c = Channel{Int}();

@mrufsvold
Copy link
Author

mrufsvold commented Oct 29, 2024

@vtjnash I don't understand the outstanding doc error. It says that the final isready(c) evaluates to true when the docstring expects false. However, when I run the code in the REPL, it matches the docstring.

Edit: I'm wondering if the comment shifted things down and confused the docstring test? It also said that take!(c) returned true, so it seems to be an issue with aligning expected and actual outputs, not with the logic of the code.

Edit 2: even after moving the comments around, it's still failing.

@vtjnash vtjnash added the merge me PR is reviewed. Merge when all tests are passing label Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs This change adds or pertains to documentation merge me PR is reviewed. Merge when all tests are passing multithreading Base.Threads and related functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants