5. Closing Channels in Go

Channels can be explicitly closed by a sender:

ch := make(chan int)

// do some stuff with the channel

close(ch)

Checking If a Channel Is Closed

Similar to the ok value when accessing data in a map, receivers can check the ok value when receiving from a channel to test if a channel was closed.

v, ok := <-ch

ok is false if the channel is empty and closed.

Don't Send on a Closed Channel

Sending on a closed channel will cause a panic. A panic on the main goroutine will cause the entire program to crash, and a panic in any other goroutine will cause that goroutine to crash.

Closing isn't necessary. There's nothing wrong with leaving channels open; they'll still be garbage collected if they're unused. You should close channels to indicate explicitly to a receiver that nothing else is going to come across.

Assignment

At Textio we're all about keeping track of what our systems are up to with great logging and telemetryarrow-up-right.

The sendReports function sends out a batch of reports to our clients and reports back how many were sent across a channel. It closes the channel when it's done.

Complete the countReports function. It should:

  • Use an infinite for loop to read from the channel

  • If the channel is closed, break out of the loop

  • Otherwise, keep a running total of the number of reports sent

  • Return the total number of reports sent

Solution

Explanation

What is inside numSentCh?

Look at sendReports:

This line is the key:

That means:

Send the integer numReports into the channel.

So the channel contains ints.

Each int represents:

The number of reports sent in one batch.

Is the channel like an array?

Not exactly.

It behaves like a stream.

Think of it like a pipe.

  • sendReports pushes numbers into one end

  • countReports reads numbers out the other end

  • When close(ch) happens, no more numbers will come

It is NOT an array. It is not stored. It is not indexed. You can only read the next value.

What is v?

In this line:

This means:

  • Read the next value from the channel

  • Store it in v

  • Store whether the channel is still open in ok

So:

  • v is the integer that was sent

  • ok is true if the channel is still open

  • ok is false if the channel is closed and empty

Example of What’s Actually Happening

Let’s say:

The loop runs 3 times:

When i = 0:

When i = 1:

When i = 2:

So the channel receives:

Then it closes.

What countReports sees

When reading from the channel:

First iteration: v = 15 Second: v = 38 Third: v = 61 Then: ok = false (channel closed)

What are we adding to total?

We do:

So we are adding:

15 + 38 + 61

Which equals:

114

So countReports returns the total number of reports sent across all batches.

Mental Model

Every time you do:

You’re grabbing the next number in the pipe.

Frequently Asked Questions

chevron-rightIs `v` representing a total number of reports sent in one batch?hashtag

Yes. Each v is the number of reports sent in that single batch.

chevron-rightIs `numSentCh` like an array?hashtag

No. It’s a stream of integers sent one at a time through a pipe.