Skip to content

[Networking] Implementing GRPCConnection #8

Description

@thep2p

Context

image

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

  • Implementing the ConnectionManager object.
  • Implementing the Connection object.
  • Implementing unit and integration tests to assess the expected behavior.

💡 Note that this issue is developed by extending the branch defining the interfaces: #7

Metadata

Metadata

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