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 docs for Channel #7673

Merged
merged 16 commits into from
Jun 4, 2019
33 changes: 33 additions & 0 deletions src/channel.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
require "fiber"

# A `Channel` enables concurrent communication between fibers.
#
# They allow communicating data between fibers without sharing memory and without having to worry about locks, semaphores or other special structures.
#
j8r marked this conversation as resolved.
Show resolved Hide resolved
# ```
j8r marked this conversation as resolved.
Show resolved Hide resolved
j8r marked this conversation as resolved.
Show resolved Hide resolved
# channel = Channel(Int32).new
#
# spawn do
# channel.send(0)
# channel.send(1)
# end
#
# channel.receive # => 0
# channel.receive # => 1
# ```
abstract class Channel(T)
module SelectAction
abstract def ready?
Expand Down Expand Up @@ -41,10 +56,24 @@ abstract class Channel(T)
@closed
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.
#
# Raises `ClosedError` if the channel is closed or closes while waiting for receive.
#
# ```
j8r marked this conversation as resolved.
Show resolved Hide resolved
# channel = Channel(Int32).new
# channel.send(1)
# channel.receive # => 1
# ```
def receive
receive_impl { raise ClosedError.new }
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.
#
# Returns `nil` if the channel is closed or closes while waiting for receive.
def receive?
receive_impl { return nil }
end
Expand Down Expand Up @@ -176,12 +205,14 @@ abstract class Channel(T)
end
end

# Buffered channel, using a queue.
class Channel::Buffered(T) < Channel(T)
def initialize(@capacity = 32)
@queue = Deque(T).new(@capacity)
super()
end

# Send a value to the channel.
def send(value : T)
while full?
raise_if_closed
Expand Down Expand Up @@ -220,6 +251,7 @@ class Channel::Buffered(T) < Channel(T)
end
end

# Unbuffered channel.
class Channel::Unbuffered(T) < Channel(T)
@sender : Fiber?

Expand All @@ -229,6 +261,7 @@ class Channel::Unbuffered(T) < Channel(T)
super
end

# Send a value to the channel.
def send(value : T)
while @has_value
raise_if_closed
Expand Down