-
Notifications
You must be signed in to change notification settings - Fork 253
Description
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