Skip to content
This repository has been archived by the owner on Feb 1, 2023. It is now read-only.

bitswap: Bitswap now sends multiple blocks per message #5

Merged
merged 2 commits into from
Oct 4, 2018

Conversation

taylormike
Copy link
Contributor

Updated PeerRequestTask to hold multiple wantlist.Entry(s). This allows Bitswap to send multiple blocks in bulk per a Peer's request. Also, added a metric for how many blocks to put in a given message. Currently: 512 * 1024 bytes.
Fixes #4378
@whyrusleeping @Stebalien

@whyrusleeping
Copy link
Member

Hey @taylormike, sorry for the wait. New repos mean i wasnt watching for notifications.

@whyrusleeping whyrusleeping self-requested a review August 30, 2018 05:01
newWorkExists = true
if blockSize, _ = e.bs.GetSize(entry.Cid); blockSize == -1 {
// Force Update Size Cache
e.bs.Get(entry.Cid)
Copy link
Member

Choose a reason for hiding this comment

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

This really shouldn't be necessary. GetSize should always work (even if it isn't cached).

Copy link
Contributor Author

@taylormike taylormike Sep 6, 2018

Choose a reason for hiding this comment

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

@Stebalien I agree, I removed the 'GetSize, then Get, then GetSize sequence'
This is done. I pushed out these changes and squashed into a single commit.

activeEntries = []*wl.Entry{}
msgSize = 0
}
activeEntries = append(activeEntries, entry.Entry)
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be in an else condition?

Copy link
Contributor Author

@taylormike taylormike Sep 6, 2018

Choose a reason for hiding this comment

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

This is intentional.
That being said, I can rewrite it as such:

  if msgSize + blockSize < maxMessageSize {
       activeEntries = append(activeEntries, entry.Entry)
       msgSize += blockSize 
       } else {
	 e.peerRequestQueue.Push(p, activeEntries...)
	 activeEntries = []*wl.Entry{}
	 msgSize = 0
       }

@@ -46,7 +46,7 @@ type prq struct {
}

// Push currently adds a new peerRequestTask to the end of the list
func (tl *prq) Push(entry *wantlist.Entry, to peer.ID) {
func (tl *prq) Push(entries []*wantlist.Entry, to peer.ID) {
Copy link
Member

Choose a reason for hiding this comment

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

API nit: While we're changing this, I'd change it to Push(to peer.ID, entries ...*wantlist.Entry).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Stebalien I agree.
This is done. I pushed out these changes and squashed into a single commit.

Copy link
Contributor

@schomatis schomatis left a comment

Choose a reason for hiding this comment

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

Very clean, nice. The message size logic seems OK. (I'm not familiarized with the rest of the code.)

@@ -231,6 +240,8 @@ func (e *Engine) MessageReceived(p peer.ID, m bsmsg.BitSwapMessage) error {
l.wantList = wl.New()
}

blockSize, msgSize := 0, 0
Copy link
Member

Choose a reason for hiding this comment

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

cleaner to write:

var blockSize, msgSize int

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@whyrusleeping I agree.
This is done. I pushed out these changes and squashed into a single commit.

newWorkExists = true
if blockSize, _ = e.bs.GetSize(entry.Cid); blockSize == -1 {
Copy link
Member

Choose a reason for hiding this comment

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

I wouldnt throw away an error. If this actually errors, something seems pretty wrong. It's worthy of logging IMO

Copy link
Contributor

Choose a reason for hiding this comment

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

There was a previous mention from @Stebalien that GetSize wouldn't fail, but maybe we could add a comment there explaining it, since yes, that silent error seems suspicious.

This really shouldn't be necessary. GetSize should always work (even if it isn't cached).

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, that statement was a bit confusing. I meant that if the Get worked, the GetSize should have worked. That is, we can just call:

size, err := e.bs.GetSize(entry.Cid)
if err != nil {
    /* we don't have it, *may* be an error, check if it's bs.ErrNotFound */
} else {
    // we have the block
}

We don't need to call GetSize, then Get, then GetSize.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@whyrusleeping, @schomatis, @schomatis I agree.
I removed the 'GetSize, then Get, then GetSize sequence' and I'm now logging the error.

This is done. I pushed out these changes and squashed into a single commit.

@taylormike
Copy link
Contributor Author

I pushed out the most recent code review feedback changes and squashed into a single commit.
I also updated bench_test, peer_request_queue_test, and engine_test accordingly.

Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

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

One small performance nit and one slightly larger concern.

When testing this, it didn't appear to have much impact until I upped the fetch concurrency quite a bit. However, I've been wanting to do that for a while anyways. Once I did that, I noticed a ~20% speedup (not counting the speedup from the increased parallelism).

Also, I wasn't able to test in a real system. I expect this'll have quite a bit more impact on a network with many peers.

newWorkExists = true
if blockSize, err = e.bs.GetSize(entry.Cid); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Actually, we should probably just use GetSize instead of Has. That way, we only make one request.

Copy link
Member

Choose a reason for hiding this comment

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

(that is, we can replace the Has check in the condition)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Stebalien
I agree, I pushed out this change and squashed into a single commit.

func taskKey(p peer.ID, k *cid.Cid) string {
func taskKey(p peer.ID, entries []*wantlist.Entry) string {
key := string(p)
for _, entry := range entries {
Copy link
Member

Choose a reason for hiding this comment

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

This is a bit unfortunate as it could grow quite large (very large). I wonder if we can switch to a different method for computing task keys.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see. This isn't actually used. Mind removing it along with the Key() function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Stebalien Sorry for the delayed response.
This is done. I pushed out this change and squashed into a single commit.

@Stebalien
Copy link
Member

I've tested this against go-ipfs and it doesn't appear to break anything.

@Stebalien
Copy link
Member

It looks like the checkHandledInOrder test is broken.

@taylormike
Copy link
Contributor Author

@Stebalien I'm looking into the checkHandledInOrder test failure.

@taylormike
Copy link
Contributor Author

@Stebalien Sorry for the delayed response.
The checkHandledInOrder test failure is now resolved. I pushed out this change and squashed into a single commit.

Updated PeerRequestTask to hold multiple wantlist.Entry(s). This allows Bitswap to send multiple blocks in bulk per a Peer's request. Also, added a metric for how many blocks to put in a given message. Currently: 512 * 1024 bytes. 

License: MIT
Signed-off-by: Jeromy <why@ipfs.io>
@ghost ghost assigned Stebalien Oct 4, 2018
@ghost ghost added the status/in-progress In progress label Oct 4, 2018
fixes bs.GetSize bug
@Stebalien
Copy link
Member

Running the go-ipfs sharness tests now.

@Stebalien
Copy link
Member

Looks good!

@Stebalien Stebalien merged commit cbd7eb7 into ipfs:master Oct 4, 2018
@ghost ghost removed the status/in-progress In progress label Oct 4, 2018
Jorropo pushed a commit to Jorropo/go-libipfs that referenced this pull request Jan 26, 2023
…dmultiple

bitswap: Bitswap now sends multiple blocks per message

This commit was moved from ipfs/go-bitswap@cbd7eb7
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants