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

[Merged by Bors] - Fix memory leaks in p2p #2351

Closed
wants to merge 14 commits into from
Closed

Conversation

lrettig
Copy link
Member

@lrettig lrettig commented Mar 27, 2021

Motivation

Closes #2313

Changes

  • Correctly close msgConn in UDP listener when closing UDP connection wrapper
  • Fix P2P incoming connection handler to correctly handle max conns

Test Plan

Adds regression tests for both fixed memory leaks:

  • test to make sure that new network connections aren't added beyond MaxPendingConnections, until one is released
  • test to make sure that msgConnection is closed when a UDP connection is evicted

TODO

  • Explain motivation or link existing issue(s)
  • Test changes and document test plan
  • Update documentation as needed

DevOps Notes

  • This PR does not require configuration changes (e.g., environment variables, GitHub secrets, VM resources)
  • This PR does not affect public APIs
  • This PR does not rely on a new version of external services (PoET, elasticsearch, etc.)
  • This PR does not make changes to log messages (which monitoring infrastructure may rely on)

p2p/net/network.go Outdated Show resolved Hide resolved
Spotter: @y0sher
@lrettig lrettig requested a review from y0sher March 28, 2021 01:49
@lrettig lrettig marked this pull request as draft March 28, 2021 01:49
@lrettig
Copy link
Member Author

lrettig commented Mar 28, 2021

Marking as draft for now as I still need to add regression tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.
Mocks the msgConn in the test. Added a very simple interface to make
this easier.
Need to init this channel manually in test
p2p/net/msgcon.go Outdated Show resolved Hide resolved
p2p/net/msgcon.go Outdated Show resolved Hide resolved
p2p/net/msgcon.go Outdated Show resolved Hide resolved
p2p/net/network.go Outdated Show resolved Hide resolved
@lrettig lrettig marked this pull request as ready for review March 30, 2021 00:29
lrettig added a commit that referenced this pull request Mar 30, 2021
Fix typo

Spotter: @y0sher

Bugfix to pass tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.

Test that msgConn is closed on UDP conn eviction

Mocks the msgConn in the test. Added a very simple interface to make
this easier.

Another test fix

Need to init this channel manually in test

Return conn token if incoming conn fails

Spotter: @y0sher

Formatting

Add regression test for net max pending conn

Fix merge conflicts and make linter happy
lrettig added a commit that referenced this pull request Mar 30, 2021
Fix typo

Spotter: @y0sher

Bugfix to pass tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.

Test that msgConn is closed on UDP conn eviction

Mocks the msgConn in the test. Added a very simple interface to make
this easier.

Another test fix

Need to init this channel manually in test

Return conn token if incoming conn fails

Spotter: @y0sher

Formatting

Add regression test for net max pending conn

Fix merge conflicts and make linter happy
lrettig added a commit that referenced this pull request Mar 30, 2021
Fix typo

Spotter: @y0sher

Bugfix to pass tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.

Test that msgConn is closed on UDP conn eviction

Mocks the msgConn in the test. Added a very simple interface to make
this easier.

Another test fix

Need to init this channel manually in test

Return conn token if incoming conn fails

Spotter: @y0sher

Formatting

Add regression test for net max pending conn

Fix merge conflicts and make linter happy

Fix concurrency issue in test
lrettig added a commit that referenced this pull request Mar 30, 2021
Fix typo

Spotter: @y0sher

Bugfix to pass tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.

Test that msgConn is closed on UDP conn eviction

Mocks the msgConn in the test. Added a very simple interface to make
this easier.

Another test fix

Need to init this channel manually in test

Return conn token if incoming conn fails

Spotter: @y0sher

Formatting

Add regression test for net max pending conn

Fix merge conflicts and make linter happy

Fix concurrency issue in test

Linter
lrettig added a commit that referenced this pull request Mar 30, 2021
Fix typo

Spotter: @y0sher

Bugfix to pass tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.

Test that msgConn is closed on UDP conn eviction

Mocks the msgConn in the test. Added a very simple interface to make
this easier.

Another test fix

Need to init this channel manually in test

Return conn token if incoming conn fails

Spotter: @y0sher

Formatting

Add regression test for net max pending conn

Fix merge conflicts and make linter happy

Fix concurrency issue in test

Linter

Minor test cleanup

Add shutdowns to tests
lrettig added a commit that referenced this pull request Mar 30, 2021
Fix typo

Spotter: @y0sher

Bugfix to pass tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.

Test that msgConn is closed on UDP conn eviction

Mocks the msgConn in the test. Added a very simple interface to make
this easier.

Another test fix

Need to init this channel manually in test

Return conn token if incoming conn fails

Spotter: @y0sher

Formatting

Add regression test for net max pending conn

Fix merge conflicts and make linter happy

Fix concurrency issue in test

Linter

Minor test cleanup

Add shutdowns to tests
}

// The connection is automatically closed when there's no more to read, no need to close it here
conn.beginEventProcessing()
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't this a blocking function so the defer call above will never be executed until beginEventProcessing terminates which is basically when the connection is closed ?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, it's blocking, that's why this whole function gets run inside a goroutine. Strictly speaking we don't need a defer here but I still think it's cleaner, more idiomatic go: this is a form of cleanup that should happen even if, e.g., there's a panic in conn.beginEventProcessing(). Let me know if you disagree.

Copy link
Contributor

Choose a reason for hiding this comment

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

the defer works and idiomatic go because we have 2 return cases. though the actual problem I see is that we're not releasing pending channel until the connection is closed, this was not what this code was intended to do once the connection is running and open it is not pending anymore and we don't need to hold the channel.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree about cleaning up and the panic case though.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I understand. The reason this is a memory leak is that we were releasing pending before closing the connection. If we do this, there can be any number of such connections at one time. Look here, you can see there are hundreds of them: #2313 (comment). This caused our managed miners to run out of memory and crash, as far as I can tell. That's why I modified this not to release until the connection closes. The current testnet is running with this code and seems stable!

lrettig added a commit that referenced this pull request Mar 31, 2021
Fix typo

Spotter: @y0sher

Bugfix to pass tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.

Test that msgConn is closed on UDP conn eviction

Mocks the msgConn in the test. Added a very simple interface to make
this easier.

Another test fix

Need to init this channel manually in test

Return conn token if incoming conn fails

Spotter: @y0sher

Formatting

Add regression test for net max pending conn

Fix merge conflicts and make linter happy

Fix concurrency issue in test

Linter

Minor test cleanup

Add shutdowns to tests
lrettig added a commit that referenced this pull request Apr 1, 2021
Fix typo

Spotter: @y0sher

Bugfix to pass tests

msgcon does not need its own closer. It's now closed from inside the UDP
wrapper. Otherwise, we get a panic on trying to close a closed channel.

Test that msgConn is closed on UDP conn eviction

Mocks the msgConn in the test. Added a very simple interface to make
this easier.

Another test fix

Need to init this channel manually in test

Return conn token if incoming conn fails

Spotter: @y0sher

Formatting

Add regression test for net max pending conn

Fix merge conflicts and make linter happy

Fix concurrency issue in test

Linter

Minor test cleanup

Add shutdowns to tests
@lrettig
Copy link
Member Author

lrettig commented Apr 21, 2021

bors merge

bors bot pushed a commit that referenced this pull request Apr 21, 2021
## Motivation
Closes #2313

## Changes
- Correctly close msgConn in UDP listener when closing UDP connection wrapper
- Fix P2P incoming connection handler to correctly handle max conns

## Test Plan
Adds regression tests for both fixed memory leaks:
- test to make sure that new network connections aren't added beyond MaxPendingConnections, until one is released
- test to make sure that msgConnection is closed when a UDP connection is evicted

## TODO
<!-- This section should be removed when all items are complete -->
- [x] Explain motivation or link existing issue(s)
- [x] Test changes and document test plan
- [ ] Update documentation as needed

## DevOps Notes
<!-- Please uncheck these items as applicable to make DevOps aware of changes that may affect releases -->
- [x] This PR does not require configuration changes (e.g., environment variables, GitHub secrets, VM resources)
- [x] This PR does not affect public APIs
- [x] This PR does not rely on a new version of external services (PoET, elasticsearch, etc.)
- [ ] This PR does not make changes to log messages (which monitoring infrastructure may rely on)
@bors
Copy link

bors bot commented Apr 21, 2021

Pull request successfully merged into develop.

Build succeeded:

@bors bors bot changed the title Fix memory leaks in p2p [Merged by Bors] - Fix memory leaks in p2p Apr 21, 2021
@bors bors bot closed this Apr 21, 2021
@bors bors bot deleted the p2p-fixleaks branch April 21, 2021 21:25
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.

Out of memory managed miner panic
3 participants