Remove libp2p-ping keep-alive functionality. (#1067)

* Fix connection & handler shutdown when using `KeepAlive::Now`.

Delay::new(Instant::now()) is never immediately ready, resulting in
`KeepAlive::Now` to have no effect, since the delay is re-created on
every execution of `poll()` in the `NodeHandlerWrapper`. It can also
send the node handler into a busy-loop, since every newly
created Delay will trigger a task wakeup, which creates a new Delay
with Instant::now(), and so forth.

The use of `Delay::new(Instant::now())` for "immediate" connection shutdown
is therefore removed here entirely. An important assumption is thereby
that as long as the node handler non-empty `negotiating_in` and `negotiating_out`,
the handler is not dependent on such a Delay for task wakeup.

* Correction to the libp2p-ping connection timeout.

The current connection timeout is always short of one `interval`,
because the "countdown" begins with the last received or sent pong
(depending on the policy). In effect, the current default config has
a connection timeout of 5 seconds (20 - 15) from the point when a ping is sent.

Instead, the "countdown" of the connection timeout should always begin
with the next scheduled ping. That also makes all configurations valid,
avoiding pitfalls.

The important properties of the ping handler are now checked to hold for all
configurations, in particular:

  * The next ping must be scheduled no earlier than the ping interval
    and no later than the connection timeout.

  * The "countdown" for the connection timeout starts on the next ping,
    i.e. the full connection timeout remains at the instant when the
    next ping is sent.

* Do not keep connections alive.

The ping protocol is not supposed to keep otherwise idle connections
alive, only to add an additional condition for terminating them in
the form of a configurable number of consecutive failed ping requests.

In this context, the `PingPolicy` does not seem useful any longer.
This commit is contained in:
Roman Borschel
2019-04-20 16:16:31 +02:00
committed by GitHub
parent 8d388d25d4
commit d5c6370b15
4 changed files with 165 additions and 108 deletions

View File

@ -20,27 +20,31 @@
//! This module implements the `/ipfs/ping/1.0.0` protocol.
//!
//! The ping protocol can be used as an application-layer keep-alive functionality
//! for connections of any [`Transport`] as well as to measure round-trip times.
//! The ping protocol can be used as a simple application-layer health check
//! for connections of any [`Transport`] as well as to measure and record
//! round-trip times.
//!
//! # Usage
//!
//! The [`Ping`] struct implements the [`NetworkBehaviour`] trait. When used with a [`Swarm`],
//! it will respond to inbound ping requests and as necessary periodically send outbound
//! ping requests on every established connection. If no pings are received or
//! successfully sent within a configurable time window, [`PingHandler::connection_keep_alive`]
//! eventually indicates to the `Swarm` that the connection should be closed.
//! ping requests on every established connection. If a configurable number of pings fail,
//! the connection will be closed.
//!
//! The `Ping` network behaviour produces [`PingEvent`]s, which may be consumed from the `Swarm`
//! by an application, e.g. to collect statistics.
//!
//! > **Note**: The ping protocol does not keep otherwise idle connections alive,
//! > it only adds an additional condition for terminating the connection, namely
//! > a certain number of failed ping requests.
//!
//! [`Swarm`]: libp2p_core::Swarm
//! [`Transport`]: libp2p_core::Transport
pub mod protocol;
pub mod handler;
pub use handler::{PingConfig, PingPolicy, PingResult, PingSuccess, PingFailure};
pub use handler::{PingConfig, PingResult, PingSuccess, PingFailure};
use handler::PingHandler;
use futures::prelude::*;