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

all: Send Close BEP msg on intentional disconnect #5440

Merged
merged 2 commits into from Jan 9, 2019

Conversation

imsodin
Copy link
Member

@imsodin imsodin commented Jan 9, 2019

Purpose

This avoids waiting until next ping and timeout until the connection is actually
closed both by notifying the peer of the disconnect and by immediately closing
the local end of the connection after that. As a nice side effect, info level
logging about dropped connections now have the actual reason in it, not a generic
timeout error which looks like a real problem with the connection.

Inspired by the logs containing tons of misleading lines about connection failures posted in https://forum.syncthing.net/t/syncthing-reconnect-disconnect-cycles-frequent/12675

Testing

Manual testing on test setup by un-/pausing folders.

This avoids waiting until next ping and timeout until the connection is actually
closed both by notifying the peer of the disconnect and by immediately closing
the local end of the connection after that. As a nice side effect, info level
logging about dropped connections now have the actual reason in it, not a generic
timeout error which looks like a real problem with the connection.
lib/model/model.go Outdated Show resolved Hide resolved
lib/model/model.go Outdated Show resolved Hide resolved
})
}

// close is called if there is an unexpected error during normal operation.
func (c *rawConnection) close(err error) {
Copy link
Member

Choose a reason for hiding this comment

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

I'm not super fond of the having both close() and Close(), the potential for confusion is enormous... I'm slightly confused even now. 😕 <- look, confused emoji

Copy link
Member Author

Choose a reason for hiding this comment

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

Is internalClose suitable? It's a bit cryptic, but so is errorClose when Close takes an error as an argument as well and I couldn't think of anything better.

c.sendClose <- asyncMessage{&Close{err.Error()}, done}
<-done

go c.commonClose(err)
Copy link
Member

Choose a reason for hiding this comment

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

Some sort of comment on why we go this? I have a vague feeling it's because this might be called from a protocol callback and there are potential deadlock issues?

Copy link
Member Author

Choose a reason for hiding this comment

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

Clear like this?

Copy link
Member

Choose a reason for hiding this comment

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

Why wouldn't we want an internal close here? Is it valid to close the connection multiple times? I assume that would panic on closing c.closed a second time. At which point the sync.once can move into the commonClose and commonClose can become internalClose?

Copy link
Member Author

Choose a reason for hiding this comment

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

You lost me there. However you made me look at it again and I found a way this can deadlock and solving that indeed gets rid of commonClose (but introduces a second once). PR incoming

@calmh
Copy link
Member

calmh commented Jan 9, 2019

This could probably take care of #3379 somehow as well

@calmh calmh merged commit 24ffd8b into syncthing:master Jan 9, 2019
@imsodin imsodin deleted the closeConn branch January 9, 2019 18:16
default:
infoMsg = "Restarted"
errMsg = "restarting"
}
Copy link
Member

Choose a reason for hiding this comment

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

This fancy shortcutting switch behaviour takes a while to process, was pretty sure at one point this was an unfinished pr.

@@ -128,6 +126,9 @@ var (
errFolderNotRunning = errors.New("folder is not running")
errFolderMissing = errors.New("no such folder")
errNetworkNotAllowed = errors.New("network not allowed")
// errors about why a connection is closed
errIgnoredFolderRemoved = errors.New("folder no longer ignored")
errReplacingConnection = errors.New("replacing connection")
Copy link
Member

Choose a reason for hiding this comment

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

I thought (back in the day), the protocol had error codes to signify the reason in a cross implementation compatible way. Is that no longer the case?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope, human readable string according to the docsé

Close

[...]

Fields

The reason field contains a human readable description of the error condition.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, it's response error code.
Perhaps we should add these errors at the protocol level, so all implementations use codes rather than strings?

c.sendClose <- asyncMessage{&Close{err.Error()}, done}
<-done

go c.commonClose(err)
Copy link
Member

Choose a reason for hiding this comment

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

Why wouldn't we want an internal close here? Is it valid to close the connection multiple times? I assume that would panic on closing c.closed a second time. At which point the sync.once can move into the commonClose and commonClose can become internalClose?

imsodin added a commit to imsodin/syncthing that referenced this pull request Jan 9, 2019
imsodin added a commit to imsodin/syncthing that referenced this pull request Jan 9, 2019
@calmh calmh modified the milestones: v1.0.2, v1.0.1 Jan 15, 2019
imsodin added a commit to imsodin/syncthing that referenced this pull request May 2, 2019
imsodin added a commit to imsodin/syncthing that referenced this pull request May 2, 2019
imsodin added a commit to imsodin/syncthing that referenced this pull request May 3, 2019
imsodin added a commit to imsodin/syncthing that referenced this pull request May 3, 2019
imsodin added a commit to imsodin/syncthing that referenced this pull request May 3, 2019
imsodin added a commit to imsodin/syncthing that referenced this pull request May 3, 2019
@st-review st-review added the frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion label Jan 10, 2020
@syncthing syncthing locked and limited conversation to collaborators Jan 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants