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

Remove main thread block on allocation #216

Merged
merged 1 commit into from
Sep 17, 2021

Conversation

hannahhoward
Copy link
Collaborator

@hannahhoward hannahhoward commented Sep 16, 2021

Goals

When memory backpressure for requests was introduced, it was introduced in such a way that not only blocks processing of further libp2p messages, but also blocks the main thread of the request manager. This may have serious side effects, as this effectively can cause the request manager to sieze up and not processing other commands like cancelling requests.

Implementation

Move potentially blocking memory allocation out of the main AsyncLoader & the internals of the main RequestManager thread, and into the per-peer thread of the libp2p message handler. This has the same effect of blocking reading further libp2p messages on the stream, and preserving memory, while at the same time not blocking the request manager thread.

Also removes parameter from AsyncLoader.ProcessResponses that is now spurious.

remote allocation from main requestmanager thread -- this could block processing of other operations
like request cancels
Copy link
Contributor

@gammazero gammazero left a comment

Choose a reason for hiding this comment

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

The code looks good, but I had a few questions that should be addressed before merging.

rm.processTerminations(filteredResponses)
select {
case <-rm.ctx.Done():
case prm.response <- nil:
Copy link
Contributor

@gammazero gammazero Sep 16, 2021

Choose a reason for hiding this comment

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

Why isn't sending nil still needed? Or was it not needed previously?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

prm.response as a field was removed in this PR I think. Waiting on the response channel was the essentially what was used to block on allocation, but that's now just being done by allocating directly in the receive handler.

@@ -31,7 +31,6 @@ type alternateQueue struct {

// Allocator indicates a mechanism for tracking memory used by a given peer
type Allocator interface {
AllocateBlockMemory(p peer.ID, amount uint64) <-chan error
ReleaseBlockMemory(p peer.ID, amount uint64) error
Copy link
Contributor

Choose a reason for hiding this comment

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

So now an Allocator interface only has a ReleaseBlockMemory method. Is Allocator still an appropriate name?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is just that go pattern of defining the interface at the site of usage. I guess we could rename it? Not sure.

totalMemoryAllocated += uint64(len(blk.RawData()))
}
select {
case <-gsr.graphSync().responseAllocator.AllocateBlockMemory(sender, totalMemoryAllocated):
Copy link
Contributor

Choose a reason for hiding this comment

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

If all the message receivers use the same allocator, would this still cause all other receivers to be blocked on memory allocation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The allocator takes a peer as a parameter cause it tracks memory allocations per peer as well as total. There's a total limit and a per peer limit. So if peer X tries to allocate above a certain amount, it will get held up seperately long before the total limit across peers gets hit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants