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

goroutine leaking when calls BindRecvChan #22

Closed
hsinhoyeh opened this issue Jul 25, 2014 · 1 comment
Closed

goroutine leaking when calls BindRecvChan #22

hsinhoyeh opened this issue Jul 25, 2014 · 1 comment
Assignees
Labels
bug Confirmed reproducible bug

Comments

@hsinhoyeh
Copy link

in netchan.go, the caller can pass a channel which reads data back via Subscribe on a topic.
https://github.com/apcera/nats/blob/master/netchan.go#L54

func (c *EncodedConn) bindRecvChan(subject, queue string, channel interface{}) error {

in the underlying implementation, nats defines a callback (i.e. cb) and then call the Subscribe from a conn
https://github.com/apcera/nats/blob/master/netchan.go#L81

_, err := c.Conn.subscribe(subject, queue, cb)

in the conn.subscribe, nats spawns a go routine to send the message:
https://github.com/apcera/nats/blob/master/nats.go#L1198

go nc.deliverMsgs(sub.mch)

and that go routine will be terminated "only if sub.mch is closed", which is called via conn.Unsubscribe().
https://github.com/apcera/nats/blob/master/nats.go#L1244

func (nc *Conn) unsubscribe(sub *Subscription, max int) error {

The bug actually happened, when we look BindRecvChan again: even the caller has closed the channel, the go routine who serves deliverMsg will never be destroyed. We actually have an additional zombie go routine when we call BindReceChan every time.

hsinhoyeh referenced this issue in hsinhoyeh/nats Jul 25, 2014
Summary:
in netchan.go, the caller can pass a channel which reads data back via Subscribe on a topic.
https://github.com/apcera/nats/blob/master/netchan.go#L54
```
func (c *EncodedConn) bindRecvChan(subject, queue string, channel interface{}) error {
```
in the underlying implementation, nats defines a callback (i.e. cb) and then call the Subscribe from a conn
https://github.com/apcera/nats/blob/master/netchan.go#L81
```
_, err := c.Conn.subscribe(subject, queue, cb)
```

in the conn.subscribe, nats spawns a go routine to send the message:
https://github.com/apcera/nats/blob/master/nats.go#L1198
```
go nc.deliverMsgs(sub.mch)
```
and that go routine will be terminated "only if sub.mch is closed", which is called via conn.Unsubscribe().
https://github.com/apcera/nats/blob/master/nats.go#L1244
```
func (nc *Conn) unsubscribe(sub *Subscription, max int) error {
```

The bug actually happened, when we look BindRecvChan again: even the caller has closed the channel, the go routine who serves deliverMsg will never be destroyed. We actually have an additional zombie go routine when we call BindReceChan every time.

Please note that this is not actually solution I thought, I prefer call it as a workaround.
I have mailed the author of nats, we may come out a better solution.
@derekcollison derekcollison self-assigned this Jul 25, 2014
@derekcollison
Copy link
Member

The proposed solution could affect ordering of messages due to the read. But great bug report. Will fix. Thanks.

derekcollison added a commit that referenced this issue Jul 25, 2014
This fixes bug #22 where Go routines were being leaked for BinnRecvChan(). Also prevents panics when the channel is closed in the program and a message is received.
olegshaldybin pushed a commit to olegshaldybin/nats that referenced this issue Aug 22, 2015
TheGhoul21 pushed a commit to TheGhoul21/nats.go that referenced this issue Jun 20, 2024
retry initial connection in now occasionally-failing reconnect test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Confirmed reproducible bug
Projects
None yet
Development

No branches or pull requests

2 participants