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

Make Base.n_avail(::Channel) public #31520

Open
eschnett opened this issue Mar 28, 2019 · 10 comments
Open

Make Base.n_avail(::Channel) public #31520

eschnett opened this issue Mar 28, 2019 · 10 comments

Comments

@eschnett
Copy link
Contributor

The function Base.n_avail(::Channel) returns how many items are currently queued in a channel. It is used internally to implement isready(::Channel).

It would be convenient if n_avail was also public and documented. I would use it e.g. to output progress information.

@StefanKarpinski
Copy link
Member

Before making anything public, can we think about consistent naming? We export bytesavailable and readavailable. If this is going to exported, it should be called navailable, available or countavailable not n_avail.

@eschnett
Copy link
Contributor Author

... or it could be length.

@StefanKarpinski
Copy link
Member

That's not a bad thought. Does it make sense to expose a container-like API for channels?

@KristofferC
Copy link
Member

If we want to call it length we should think what generic function you can write that work both on e.g. arrays and channels using length.

@eschnett
Copy link
Contributor Author

isempty(ch) = length(ch) == 0

Using length, you could handle channeled data in batches. In my use case, I want to upload data to a web service in batches. I'm currently using an iterator (which works for both arrays and channels), and I'm using channels of vectors to allow for batching:

function files_upload(auth::Authorization,
                      path::String,
                      content_channel::Union{AbstractChannel{Vector{UInt8}},
                                             AbstractVector{Vector{UInt8}}}
                      )::FileMetadata

You might need a few other functions, e.g.

popfirst!(ch) = take!(ch)
push!(ch) = put!(ch)

However, I wouldn't compare Channel and Array. I would compare Channel and Queue.

@JeffBezanson
Copy link
Member

This is not a length --- most importantly, it's unrelated to how many items you will get by iterating. n_avail and isready need to be considered basically performance hints; they have no clear meaning within the channel abstraction. In other words, the values they return say nothing about what will happen when you use the intended API (put, take), except perhaps performance. A progress meter is also a valid application. But code shouldn't depend on them in any "serious" way.

Thinking of it another way, the purpose of channels is basically synchronization. If you use them like an array, then you lose that and you're back to your code being as racy as if you just used an array.

@KristofferC
Copy link
Member

However, I wouldn't compare Channel and Array. I would compare Channel and Queue.

The point is the generic function length. If it is extended Base.length is should have the same meaning as Base.length. Otherwise you are doing interface piracy (yeah I just made that word up).

@vtjnash
Copy link
Member

vtjnash commented Mar 28, 2019

That's true if there's multiple consumers, but actually it's sometimes valid (and not race-y) to use these operations, for example if you only plan to have one consumer (and any number of producers to synchronize with). Sort of an odd asymmetry to consider, but it's theoretically meaningful to call it length in those cases (I have no idea if it's useful, just saying it's possible).

@JeffBezanson
Copy link
Member

I think even then it's not a length, since it doesn't tell you how many values you will get.

@laborg
Copy link
Contributor

laborg commented Oct 18, 2023

Related: #12781

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants