Skip to content

ConnManager should be able to create connectionsΒ #870

@lthibault

Description

@lthibault

Abstract

ConnManager is positioned as an interface that provides "connection tracking and management interfaces for libp2p", yet it only allows implementations to prune connections. This is useful for placing an upper bound on a host's resource usage, but many applications also need to take action when there are too few connections to a host.

I propose a simple improvement to the ConnManager subpackage, which allows implementors create connections according to user-defined logic, for example if the connection count falls below a low-water mark. The proposed changes maintain backwards compatibility and are of great utility to application developers concerned with maintaining homeostasis in their clusters.

I am happy to provide a pull-request with these changes if there's any interest. Thank you in advance for your kind consideration, and for the outstanding work on this library!

Motivation

I am currently working on an application to manage computational resources in a cloud environment. This application uses go-libp2p-pubsub to periodically send cluster-wide heartbeat messages. pubsub.PubSub requires that the host already be connected to at least one other in order for the overlay network to self-assemble; even with DHT routing in place, PubSub won't create the first connection automatically.

Because connections may spontaneously drop, this opens the possibility that a Host becomes orphaned and unable to re-join the cluster. To mitigate against this, I would like to automatically create connections with randomly-selected peers (from the host's Peerstore) if the connection count drops below an arbitrary low-water mark. Ideally, this should be handled by a ConnManager, as this seems like a logical place to encapsulate connection management in general.

In order to implement the aforementioned logic, the ConnManager needs a reference to both network.Network and peerstore.Peerstore. The simplest way to achieve this is for ConnManager to hold a reference to host.Host, but this is made difficult by the fact that hosts expect their ConnManagers to be passed in as arguments to lip2p.New.

Proposal

The following solution satisfies the above constraints, without breaking backwards-compatibility, and without requiring any modifications to existing ConnManager implementations.

The first step is to add an optional interface to go-libp2p-core/connmgr:

type HostSetter interface {
    SetHost(context.Context, host.Host)
}

From there, a couple of lines need to be added to Config.NewNode exactly here:

// ...

if s, ok := cfg.ConnManager.(connmgr.HostSetter); ok {
    s.SetHost(ctx, h)
}

// ...

This allows user-defined connection-management code to run until the context expires.

Conclusion

Again, I'm more than happy to issue a PR for these changes. Please let me know if I should begin work!

I hope everyone is doing well in spite of the pandemic πŸ˜ƒ

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions