Replies: 5 comments 3 replies
-
Realistically, what you need is a muxer that allows back-pressure on the number of streams. QUIC can do that for example or qmux. In the absence of a back-pressure mechanism (yamux doesn't have one), we can only drop incoming streams.
Source: https://apenwarr.ca/log/20170814 I am not sure if it is possible to implement a backwards-compatible mechanism to signal that we are intentionally dropping the stream. As part of #3014 I want to change yamux such that we can observe a stream reset without having written a single byte to the stream. That would cause the stream to be aborted with |
Beta Was this translation helpful? Give feedback.
-
Given that currently deployed libp2p software cannot recognise this type of backpressure, my assessment is that this change broke network compatibility and needs to be reverted. Adding backpressure is a worthy goal, but it needs to be done such that existing peers expect it and can handle it. Since yamux has no reliable tools for this task, my proposal would be to
/cc @mxinden |
Beta Was this translation helpful? Give feedback.
-
Thanks @rkuhn for tracing this all the way back. Sorry for this not being easier to discover. First off, I would like to differentiate two types of inbound streams:
Also, just to avoid confusion, all the limits we are talking about here are per connection, i.e. between two endpoints. Not for all connections of a given peer.
The limit on inbound negotiating streams was introduced with #2697. Without this limit a remote can open a large amount of streams towards the local node. Given that the local node allocates some memory for each of these streams, the local node eventually runs out of memory. I would not refer to this mechanism as a backpressure mechanism, but as a last-resort DOS prevention mechanism. #2796 and #2861 did not introduce this limit, but instead moved this limit. Instead of dropping inbound streams within the Given that Yamux breaks the backpressure chain, i.e. does not communicate the limit to the remote but drops streams, we don't actually enforce backpressure with Yamux. #2796 does pave the way for proper backpressure on streams for QUIC and the future qmux.
First we would have to agree on a magic number. Second this would need to be rolled out to a live network in two steps, given that these limits are never communicated in-band. First this needs to be rolled out for the stream outbound side and then the stream inbound side. I think it makes more sense for us to invest in QUIC and sometime in the future into qmux.
Note that you can set a very high limit and thus achieve the old behavior ( My suggestion moving forward here:
I am very eager to take you up on this offer. I think we can learn a lot from your experience here. If you are up for it, I would suggest to start with a call with @thomaseizinger and me. I will try to schedule something out-of-band. |
Beta Was this translation helpful? Give feedback.
-
Yes, that’ll be my path once #3041 is resolved (because the limit I’m currently hitting is not configurable).
Yes, I do think that bitswap should receive some tender loving care. I am hesitant to construct workarounds, though, since I think the back-pressure aware core API will require a rather different approach (like new substream requests being pulled from bitswap only when there is room to send them). After some brainstorming we should create discussions and issues here as we gain more clarity on how to proceed in the big picture. |
Beta Was this translation helpful? Give feedback.
-
As a hotfix, we can expose a configuration option for this when constructing the yamux multiplexer. Thoughts on that @mxinden @rkuhn ? We can make a patch release for that so it is immediately available. |
Beta Was this translation helpful? Give feedback.
-
Since the implementation of #2796 outbound substreams may fail to negotiate due to an excess of inbound substreams on the remote end. Unfortunately the signal that I see in libp2p-bitswap is only this:
It would be great to get a better diagnostic than “UnsupportedProtocols”. But even so, it is unclear to me how to correctly implement backpressure in this environment:
My current impression — hopefully misguided — is that I need to do something akin to reimplementing TCP on top of UDP. Until then I’ll probably have to set the inbound substream limit to an extremely high value.
Beta Was this translation helpful? Give feedback.
All reactions