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

Backpressure between components #3078

Open
1 of 15 tasks
mxinden opened this issue Nov 3, 2022 · 3 comments
Open
1 of 15 tasks

Backpressure between components #3078

mxinden opened this issue Nov 3, 2022 · 3 comments
Labels
tracking-issue Issues which are the entry point to bigger projects.

Comments

@mxinden
Copy link
Member

mxinden commented Nov 3, 2022

What is backpressure

A slow consumer should slow down (i.e. backpressure) a fast producer.

Why do we need backpressure

  • Prevent unbounded growth of buffers.
  • Potential DOS defense.
  • Potential lower latencies.
  • Potential better resource allocation.

See also coding guidelines - Bound everything.

Where do we enforce backpressure

  • User -> Swarm

    • No backpressure
    • Useful when dialing a lot of peers via Swarm::dial.
    • ConnectionLimit enforces boundedness at least in the Pool.
    • Might not be worth fixing, i.e. bursts might be fine.
  • User -> NetworkBehaviour

    • No backpressure
    • User can access NetworkBehaviour via Swarm::behaviour_mut
    • Useful e.g. when doing large amounts of DHT lookups via libp2p-kad, many libp2p-request-response requests, ...
    • Potential solution
      • In the case of libp2p-kad have a Kademlia::poll_find_closest_ready that needs to be polled before Kademlia::find_closest similar to Sink::poll_ready.
  • Swarm -> NetworkBehaviour

    • No backpressure
    • Only system notification events (e.g. connection established), thus not important.
    • Inbound connection
  • NetworkBehaviour -> ConnectionHandler

    • No backpressure
    • Swarm does not poll NetworkBehaviour in case it could not deliver previously returned event from the NetworkBehaviour to the destined ConnectionHandler.

      rust-libp2p/swarm/src/lib.rs

      Lines 1032 to 1034 in f9b4af3

      match this.pending_event.take() {
      // Try to deliver the pending event emitted by the [`NetworkBehaviour`] in the previous
      // iteration to the connection handler(s).
    • NetworkBehaviour is blocked on single slow ConnectionHandler
    • Potential solutions
      • Drop the event
        • NetworkBehaviour already needs to handle the case where the connection closes and thus the event is never delivered to the ConnectionHandler.
        • When sending two events, first might be dropped (ConnectionHandler busy) while the second might be delivered. Not intuitive.
      • Return event back to the NetworkBehaviour
      • Add NetworkBehaviour::poll_connection_handler_event, providing a list of ConnectionIds with ConnectionHandlers that are ready to receive another event.
  • NetworkBehaviour -> Swarm

    • NetworkBehaviourAction::Dial
  • ConnectionHandler -> NetworkBehaviour

    • Backpressure
    • ConnectionHandler is blocked on slow NetworkBehaviour
    • Expected behaviour
  • Connection -> ConnectionHandler

    • ConnectionHandler::inject_fully_negotiated_inbound
      • Inbound can only drop
      • how about poll_inbound_ready
      • Note that multistream-select needs to run first, otherwise we can't map to a specific ConnectionHandler
    • ConnectionHandler::inject_fully_negotiated_outbound
      • how about poll_outbound_substream
      • Or the ConnectionHandler needs to internally enforce a limit of pending outbound connections. (Lots of duplication given the amount of ConnectionHandlers)
    • ConnectionHandler::inject_event
      • No backpressure
      • Possible solution
        • Add ConnectionHandler::poll_inject_event_ready
  • ConnectionHandler -> Connection

    • ConnectionHandlerEvent::OutboundSubstreamRequest
      • Can only be dropped
  • Stream

Related resources

@thomaseizinger
Copy link
Contributor

Relevant discussion happening here: #3411.

@mxinden
Copy link
Member Author

mxinden commented Mar 30, 2023

Cross-referencing backpressure tracking issue for Kademlia here #3710.

@thomaseizinger thomaseizinger changed the title [Tracking Issue] Backpressure Backpressure between components Sep 19, 2023
@thomaseizinger thomaseizinger added tracking-issue Issues which are the entry point to bigger projects. and removed priority:important The changes needed are critical for libp2p, or are blocking another project difficulty:hard labels Sep 19, 2023
@thomaseizinger
Copy link
Contributor

Cross-referencing a discussion around backpressure: #4585.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tracking-issue Issues which are the entry point to bigger projects.
Projects
None yet
Development

No branches or pull requests

2 participants