fill in implementation notes section

This commit is contained in:
Yusef Napora
2019-05-30 11:58:15 -04:00
parent b4131cb4e4
commit c898e1f77e

View File

@@ -223,16 +223,98 @@ provided.
## Practical Considerations
This section will go over a few aspects of connection establishment and state
management that are worth considering when implementing libp2p.
### Interoperability
### Dialer State Management
Support for connection security protocols and stream multiplexers varies across
libp2p implementations.
To support the widest variety of peers, implementations should support a
baseline "stack" of security and multiplexing protocols.
At the time of writing, the recommended baseline security protocol is
[SECIO][secio-spec], which is supported in all current libp2p implementations.
Note that while SECIO is also the current default security protocol, that is
likely to change with the further adoption of [TLS][tls-libp2p]. However,
support for SECIO as a fallback will likely be recommended for some time after
TLS becomes the default.
The recommended baseline stream multiplexer is [mplex][mplex], which provides a
very simple programmatic API and is supported in all current libp2p
implementations.
### State Management
While the connection establishment process itself does not require any
persistent state, some state management is useful to assist bootstrapping and
maintain resource limits.
#### Peer Metadata Storage
### Connection Management
It's recommended that libp2p implementations provide a persistent metadata
storage interface that contains at minimum the peer id and last known valid
addresses for each peer. This allows you to more easily "catch
back up" and rejoin a dense network between invocations of your libp2p
application without having to rely on a few bootstrap nodes and random DHT walks
to build up a routing table.
Even during a single invocation of an application, you're likely to benefit from
an in-memory metadata storage facility, which will allow you to cache addresses
for connection resumption. Desining a storage interface which can be backed by
memory or persistent storage will let you swap in whichever is appropriate for
your use case and stage of development.
For examples, see
[go-libp2p-peerstore](https://github.com/libp2p/go-libp2p-peerstore) and
[js-peer-book](https://github.com/libp2p/js-peer-book).
#### Connection Limits
Maintaining a large number of persistent connections can cause issues with some
network environments and can lead to resource exhaustion and erratic behavior.
It's highly recommended that libp2p implementations maintain an upper bound on
the number of open connections. Doing so while still maintaining robust
performance and connectivity will likely require implementing some kind of
priority mechanism for selecting which connections are the most "expendable"
when you're near the limit.
Resource allocation, measurement and enforcement policies are all an active area
of discussion in the libp2p community, and implementations are free to develop
whatever prioritization system makes sense.
### Connection Lifecycle Events
The establishment of new connections and streams is likely to be a
"cross-cutting concern" that's of interest to various parts of your application
(or parts of libp2p) besides the protocol handlers that directly deal with the
traffic.
For example, the [persistent metadata component](#peer-metadata-storage) could
automatically add peer ids and addresses to its registry whenever a new peer
connects, or a DHT module could update its routing tables when a connection is
terminated.
To support this, it's recommended that libp2p implementations support a
notification or event delivery system that can inform interested parties about
connection lifecycle events.
The full set of lifecycle events is not currently specified, but a recommended
baseline would be:
| Event | Description |
|--------------|-------------------------------------------|
| Connected | A new connection has been opened |
| Disconnected | A connection has closed |
| OpenedStream | A new stream has opened over a connection |
| ClosedStream | A stream has closed |
| Listen | We've started listening on a new address |
| ListenClose | We've stopped listening on an address |
[mss]: https://github.com/multiformats/multistream-select
[uvarint]: https://github.com/multiformats/unsigned-varint
[mplex]: ../mplex/README.md