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

Add documentation for Channel#send and Channel#close (crystal-lang#8346) #8356

Merged
merged 6 commits into from
Nov 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 12 additions & 1 deletion spec/std/channel_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ describe Channel do
ch2.receive.should eq 2
end

it "does not raise or change its status when it is closed more than once" do
ch = Channel(Int32).new
ch.closed?.should be_false

ch.close
ch.closed?.should be_true

ch.close
ch.closed?.should be_true
end

describe ".select" do
context "receive raise-on-close single-channel" do
it "types" do
Expand Down Expand Up @@ -512,7 +523,7 @@ describe "unbuffered" do
closed.should be_true
end

it "can send suceesfully without raise" do
it "can send successfully without raise" do
ch = Channel(Int32).new
raise_flag = false

Expand Down
18 changes: 16 additions & 2 deletions src/channel.cr
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ class Channel(T)
end
end

# Closes the channel.
# The method prevents any new value from being sent to / received from the channel.
# All fibers blocked in `send` or `receive` will be awakened with `Channel::ClosedError`
#
# Both awaiting and subsequent calls to `#send` will consider the channel closed.
# All items successfully sent to the channel can be received, before `#receive` considers the channel closed.
# Calling `#close` on a closed channel does not have any effect.
def close : Nil
sender_list = Crystal::PointerLinkedList(Sender(T)).new
receiver_list = Crystal::PointerLinkedList(Receiver(T)).new
Expand All @@ -186,6 +193,11 @@ class Channel(T)
@closed
end

# Sends a value to the channel.
# If the channel has spare capacity, then the method returns immediately.
# Otherwise, this method blocks the calling fiber until another fiber calls `#receive` on the channel.
#
# Raises `ClosedError` if the channel is closed or closes while waiting on a full channel.
def send(value : T)
sender = Sender(T).new

Expand Down Expand Up @@ -237,13 +249,15 @@ class Channel(T)
end

# Receives a value from the channel.
# If there is a value waiting, it is returned immediately. Otherwise, this method blocks until a value is sent to the channel.
# If there is a value waiting, then it is returned immediately. Otherwise, this method blocks until a value is sent to the channel.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added then for consistency with the docs above - both are valid, I believe

#
# Raises `ClosedError` if the channel is closed or closes while waiting for receive.
#
# ```
# channel = Channel(Int32).new
# channel.send(1)
# spawn do
# channel.send(1)
# end
Copy link
Contributor Author

Choose a reason for hiding this comment

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

An alternative way to fix the code snippet would be to go buffered

channel = Channel(Int32).new(1)
channel.send(42)
channel.receive # => 42

# channel.receive # => 1
# ```
def receive
Expand Down