Function libp2p_swarm_test::drive

source ·
pub async fn drive<TBehaviour1, const NUM_EVENTS_SWARM_1: usize, Out1, TBehaviour2, const NUM_EVENTS_SWARM_2: usize, Out2>(
    swarm1: &mut Swarm<TBehaviour2>,
    swarm2: &mut Swarm<TBehaviour1>
) -> ([Out1; NUM_EVENTS_SWARM_1], [Out2; NUM_EVENTS_SWARM_2])
where TBehaviour2: NetworkBehaviour + Send, TBehaviour2::ToSwarm: Debug, TBehaviour1: NetworkBehaviour + Send, TBehaviour1::ToSwarm: Debug, SwarmEvent<TBehaviour2::ToSwarm>: TryIntoOutput<Out1>, SwarmEvent<TBehaviour1::ToSwarm>: TryIntoOutput<Out2>, Out1: Debug, Out2: Debug,
Expand description

Drives two Swarms until a certain number of events are emitted.

Usage

Number of events

The number of events is configured via const generics based on the array size of the return type. This allows the compiler to infer how many events you are expecting based on how you use this function. For example, if you expect the first Swarm to emit 2 events, you should assign the first variable of the returned tuple value to an array of size 2. This works especially well if you directly pattern-match on the return value.

Type of event

This function utilizes the TryIntoOutput trait. Similar as to the number of expected events, the type of event is inferred based on your usage. If you match against a SwarmEvent, the first SwarmEvent will be returned. If you match against your NetworkBehaviour::ToSwarm type, SwarmEvents which are not SwarmEvent::Behaviour will be skipped until the Swarm returns a behaviour event.

You can implement the TryIntoOutput for any other type to further customize this behaviour.

Difference to [futures::future::join]

This function is similar to joining two futures with two crucial differences:

  1. As described above, it allows you to obtain more than a single event.
  2. More importantly, it will continue to poll the Swarms even if they already has emitted all expected events.

Especially (2) is crucial for our usage of this function. If a Swarm is not polled, nothing within it makes progress. This can “starve” the other swarm which for example may wait for another message to be sent on a connection.

Using drive instead of [futures::future::join] ensures that a Swarm continues to be polled, even after it emitted its events.