Context
In our implementation of a Skip Graph, the connection between two Skip Graph node is managed through each side of the connection implementing a Connection object. Under the hood, the connection object acts as a wrapper around a gRPC bidirectional streaming connection. A connection object implements the Connection interface as below:
// Connection represents a connection to a remote peer.
type Connection interface {
// RemoteAddr returns the remote address of the connection.
// It returns an empty string if the connection is closed, otherwise it returns the remote address,
// which is the address of the peer that the connection is connected to.
RemoteAddr() string
// Send sends a message to the remote peer, returning an error if the message could not be sent.
// Send is a blocking operation, and it will block until the message is sent.
// It returns an error if the message could not be sent.
// It returns io.EOF if the connection is closed.
Send([]byte) error
// Next returns the next message received from the remote peer.
// It is a blocking operation, and it will block until a message is received.
// It returns io.EOF if the connection is closed.
// It returns an error if the message could not be read.
Next() ([]byte, error)
// Close gracefully closes the connection. Blocking until the connection is closed.
Close() error
}
The ConnectionManager is tasked with establishing and maintaining the connections. By default, there is at most one connection between two peers.
// ConnectionManager establishes and maintains connections.
type ConnectionManager interface {
// Connect establishes a connection to a remote peer and locally caches and returns the connection.
// If the connection is already established, it returns the cached connection.
// The cardinal assumption is there is always at most one connection to a remote peer.
Connect(context.Context, skipgraph.Identifier) (Connection, error)
// Close closes all connections.
// No error is expected under normal circumstances.
Close() error
}
When node A attempts to Connect to node B:
- If there is already a connection established to node
B; that existing connection is returned.
- Otherwise,
ConnectionManager on node A dials a connection to node B, i.e., establishing a gRPC bidirectional streaming acting node A as the client and node B as the server. Upon the connection is established, the ConnectionManagers on both nodes A and B cache the connection.
Definition of Done
💡 Note that this issue is developed by extending the branch defining the interfaces: #7
Context
In our implementation of a Skip Graph, the connection between two Skip Graph node is managed through each side of the connection implementing a
Connectionobject. Under the hood, the connection object acts as a wrapper around a gRPC bidirectional streaming connection. A connection object implements theConnectioninterface as below:The
ConnectionManageris tasked with establishing and maintaining the connections. By default, there is at most one connection between two peers.When node
Aattempts toConnectto nodeB:B; that existing connection is returned.ConnectionManageron nodeAdials a connection to nodeB, i.e., establishing a gRPC bidirectional streaming acting nodeAas the client and nodeBas the server. Upon the connection is established, theConnectionManagers on both nodesAandBcache the connection.Definition of Done
ConnectionManagerobject.Connectionobject.💡 Note that this issue is developed by extending the branch defining the interfaces: #7