Why does this channel-based pub/sub broker panic?

179 views
Skip to first unread message

cpu...@gmail.com

unread,
Mar 4, 2025, 8:40:55 AMMar 4
to golang-nuts
I've recently run across  https://stackoverflow.com/questions/36417199/how-to-broadcast-message-using-channel by icza and tried to use the simple broker in my project.

Unfortunately, it panics with send on closed channel. I couldn't figure out why or where and created a reproducer: https://play.golang.com/p/8hrHf4-nGY2

Can someone spot why this would panic (except for the obvious reason) and how to fix it?

Cheers,
Andi

Jan Mercl

unread,
Mar 4, 2025, 8:51:41 AMMar 4
to cpu...@gmail.com, golang-nuts
I didn't analyze the code, but maybe this can help:
https://play.golang.com/p/Ix003aXFFul

cpu...@gmail.com

unread,
Mar 4, 2025, 8:54:41 AMMar 4
to golang-nuts
Thanks Jan, but this just confirms that there is a send on a closed channel. 

It makes me wonder though (far, very far shot): given the map of subscriptions is using the new swissmap, might that be a bug with that? As I've said- very long shot.

Cheers,
Andi

Robert Engels

unread,
Mar 4, 2025, 9:01:37 AMMar 4
to cpu...@gmail.com, golang-nuts
You can’t make the unsubscribe channel buffered. 

On Mar 4, 2025, at 7:55 AM, cpu...@gmail.com <cpu...@gmail.com> wrote:

Thanks Jan, but this just confirms that there is a send on a closed channel. 
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/c1a2ed5f-6b94-4acc-8d8f-465131e74651n%40googlegroups.com.

cpu...@gmail.com

unread,
Mar 4, 2025, 9:03:38 AMMar 4
to golang-nuts
Thanks Robert,

did a quick try and still panics. This seems to make sense- the unsubscribe is the root cause of the panic- while it's still in the buffer the channel won't be closed.

Cheers,
Andi

Jan Mercl

unread,
Mar 4, 2025, 9:03:55 AMMar 4
to cpu...@gmail.com, golang-nuts
On Tue, Mar 4, 2025 at 2:55 PM cpu...@gmail.com <cpu...@gmail.com> wrote:

> Thanks Jan, but this just confirms that there is a send on a closed channel.

It shows the code is "actively" closing a channel that will be later
used for sending. Meaning the problem is possibly not in the send, but
in the close.

Robert Engels

unread,
Mar 4, 2025, 9:09:11 AMMar 4
to cpu...@gmail.com, golang-nuts
Actually all if the channels need to be unbuffered. Otherwise you have pending data that isn’t read when the channel is closed. When I make them all unbuffered it works. 

On Mar 4, 2025, at 8:04 AM, cpu...@gmail.com <cpu...@gmail.com> wrote:

Thanks Robert,

Robert Engels

unread,
Mar 4, 2025, 9:16:54 AMMar 4
to cpu...@gmail.com, golang-nuts
I think this is applicable 

On Mar 4, 2025, at 8:08 AM, Robert Engels <ren...@ix.netcom.com> wrote:



cpu...@gmail.com

unread,
Mar 4, 2025, 9:22:34 AMMar 4
to golang-nuts
Thanks Robert,

with unbuffered channels it doesn't panic- but the play also doesn't end. Debugger confirms "all go routines asleep" (not sure why).
I'd also still be confused why the (un)subscribe channels should matter. As long as (in unsubscribe) the msgCh hasn't been removed it can still be sent to, buffering wouldn't change that.

Thanks for your interest in chasing this :)

Cheers,
Andi

Robert Engels

unread,
Mar 4, 2025, 9:39:43 AMMar 4
to cpu...@gmail.com, golang-nuts
I figured it out. Because the subscribe channel is buffered. Technically the broker can see the unsubscribe for the client before the subscribe message. So it closes the channel then tries to send on it. 

cpu...@gmail.com

unread,
Mar 4, 2025, 10:10:25 AMMar 4
to golang-nuts
Great find, confirmed. Since subscribe is not executed synchronously due to buffering, unsubscribe may execute first, close the channel, and then subscribes puts the closed channel into the subscriptions.

THANK YOU!

Robert Engels

unread,
Mar 4, 2025, 10:11:54 AMMar 4
to cpu...@gmail.com, golang-nuts
To elaborate, by the time the select loop runs in the broker, but the subscribe and unsubscribe channels for a particular client could be ready - which one is read is undefined - thus the send after close. 

On Mar 4, 2025, at 8:38 AM, Robert Engels <ren...@ix.netcom.com> wrote:



ren...@ix.netcom.com

unread,
Mar 5, 2025, 1:03:34 AMMar 5
to golang-nuts
You’re welcome. 

ren...@ix.netcom.com

unread,
Mar 5, 2025, 1:10:11 AMMar 5
to golang-nuts
Btw, with all respect to Mr Pike, the idea that concurrency is simpler if you do not share data is a bit of an over simplification imo. You still need to be able to understand concurrent concepts or you will experience a lot of pain. There is no free lunch. 

On Tuesday, March 4, 2025 at 9:10:25 AM UTC-6 cpu...@gmail.com wrote:
Reply all
Reply to author
Forward
0 new messages