Recommended way to use len() on a channel safely

I recently learned you can use len() on a channel type. But this obviously sounds like a bad idea if you need for an accurate count: by the time you get the value and use it, other goroutines may have read from or sent to the channel.

From what I’ve read, most people just use this to get a general idea of the count for some simple load balancing tasks. But if you do need an accurate count, what is a good, safe way to do this? It seems like locking the channel operations would get messy fast and is poor style… so just keep track of the count yourself with sync/atomic, maybe?

1 Like

I didn’t know len() worked against a channel. I need to try that. My guess is like anything you would need to Mutex access so in some given space and time the count is accurate.

Yes, len is fine for statistics but using it for logic is inherently racy in the absence of other locks. You could use it reliably if you always lock before using the channel, and hold the lock until you’ve use the result of len. But if you are doing that, then perhaps the channel is not the right data structure anyhow–you could also lock around all operations on a slice, for example, and that might be more efficient for your use case.

7 Likes

I’ve used len() on channels in some rare cases (usually don’t really need it) where the purpose of the channel is strictly to fan in data and there is a single consumer/worker. It comes handy if you use the channel as a buffer for structs.