Skip to content

MessageSender limits concurrent RPCs to remote peer by only keeping one single stream per peer  #805

@cortze

Description

@cortze

I've been conducting many concurrent CID Provide() and FindProviders() operations for RFM17 and RFM17.1 and I spotted a significant bottleneck in the current MessageSender's logic that affects the concurrency implementations on top of the go-libp2p-kad-dht.

As the messageSenderImpl suggests, The DHT implementation is limited to a single stream per peer.

// messageSenderImpl is responsible for sending requests and messages to peers efficiently, including reuse of streams.
// It also tracks metrics for sent requests and messages.
type messageSenderImpl struct {
	host      host.Host // the network services we need
	smlk      sync.Mutex
	strmap    map[peer.ID]*peerMessageSender
	protocols []protocol.ID
}

From a conversation I had with @mxinden about "Back Pressure" this logic seems wrong, as we should prioritize opening a new stream over sending multiple RPCs in the same stream. However, this is not even the case in the implementation. The current peerMessageSender only puts one single RPC at a time; therefore, multiple provide/lookup operations remain idle, waiting to get some "stream-time".

// peerMessageSender is responsible for sending requests and messages to a particular peer
type peerMessageSender struct {
	s  network.Stream
	r  msgio.ReadCloser
	lk internal.CtxMutex
	p  peer.ID
	m  *messageSenderImpl

	invalid   bool
	singleMes int
}

There is a significant margin for improvement if we come up with a better strategy to open/handle streams with remote IPFS nodes, so I open the Issue and the discussion to find the best way of improving it.

cc: @Jorropo @yiannisbot

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions