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

Fix channel data race #558

Merged
merged 1 commit into from
Jun 30, 2021

Conversation

wolfstudy
Copy link
Member

Signed-off-by: xiaolongran xiaolongran@tencent.com

Motivation

In internalSendRequest, We will add the request to be sent to the pendingReqs map, even when the current connection status is connectionClosed, we will append the request, which will cause the current request's callback to be called twice

First:

func (c *connection) internalSendRequest(req *request) {
	c.pendingLock.Lock()
	if req.id != nil {
		c.pendingReqs[*req.id] = req
	}
	c.pendingLock.Unlock()
	if c.getState() == connectionClosed {
		c.log.Warnf("internalSendRequest failed for connectionClosed")
                // In Here, call req.callback *************
		if req.callback != nil {
			req.callback(req.cmd, ErrConnectionClosed)
		}
	} else {
		c.writeCommand(req.cmd)
	}
}

Twice:

func (c *connection) run() {
	// All reads come from the reader goroutine
	go c.reader.readFromConnection()
	go c.runPingCheck()

	c.log.Debugf("Connection run starting with request capacity=%d queued=%d",
		cap(c.incomingRequestsCh), len(c.incomingRequestsCh))

	defer func() {
		// all the accesses to the pendingReqs should be happened in this run loop thread,
		// including the final cleanup, to avoid the issue https://github.com/apache/pulsar-client-go/issues/239
		c.pendingLock.Lock()
		for id, req := range c.pendingReqs {
                         // In Here, call req.callback **********
			req.callback(nil, errors.New("connection closed"))
			delete(c.pendingReqs, id)
		}
		c.pendingLock.Unlock()
		c.Close()
	}()
       ....
}

In fact, when the current connection is in the connectionClosed state, we don’t need to append the request to the pendingReqs map, so we don’t need to process the request when it’s closed.

Modifications

When the connection is closed, the current request to be sent is not added to the pendingReqs map.

Signed-off-by: xiaolongran <xiaolongran@tencent.com>
@wolfstudy wolfstudy self-assigned this Jun 30, 2021
@wolfstudy wolfstudy added this to the 0.6.0 milestone Jun 30, 2021
@wolfstudy
Copy link
Member Author

@freeznet @zymap PTAL thanks.

@wolfstudy wolfstudy requested a review from zymap June 30, 2021 11:15
Copy link
Contributor

@freeznet freeznet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wolfstudy wolfstudy merged commit ea3e054 into apache:master Jun 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants