github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/conduit.go (about)

     1  package network
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/onflow/flow-go/model/flow"
     9  	"github.com/onflow/flow-go/network/channels"
    10  )
    11  
    12  // ConduitFactory is an interface type that is utilized by the Network to create conduits for the channels.
    13  type ConduitFactory interface {
    14  	// RegisterAdapter sets the ConduitAdapter component of the factory.
    15  	// The ConduitAdapter is a wrapper around the Network layer that only exposes the set of methods
    16  	// that are needed by a conduit.
    17  	RegisterAdapter(ConduitAdapter) error
    18  
    19  	// NewConduit creates a conduit on the specified channel.
    20  	// Prior to creating any conduit, the factory requires an ConduitAdapter to be registered with it.
    21  	NewConduit(context.Context, channels.Channel) (Conduit, error)
    22  }
    23  
    24  // Conduit represents the interface for engines to communicate over the
    25  // peer-to-peer network. Upon registration with the network, each engine is
    26  // assigned a conduit, which it can use to communicate across the network in
    27  // a network-agnostic way. In the background, the network layer connects all
    28  // engines with the same ID over a shared bus, accessible through the conduit.
    29  type Conduit interface {
    30  	MisbehaviorReporter
    31  	// Publish submits an event to the network layer for unreliable delivery
    32  	// to subscribers of the given event on the network layer. It uses a
    33  	// publish-subscribe layer and can thus not guarantee that the specified
    34  	// recipients received the event.
    35  	// The event is published on the channels of this Conduit and will be received
    36  	// by the nodes specified as part of the targetIDs.
    37  	// TODO: function errors must be documented.
    38  	Publish(event interface{}, targetIDs ...flow.Identifier) error
    39  
    40  	// Unicast sends the event in a reliable way to the given recipient.
    41  	// It uses 1-1 direct messaging over the underlying network to deliver the event.
    42  	// It returns an error if the unicast fails.
    43  	// TODO: function errors must be documented.
    44  	Unicast(event interface{}, targetID flow.Identifier) error
    45  
    46  	// Multicast unreliably sends the specified event over the channel
    47  	// to the specified number of recipients selected from the specified subset.
    48  	// The recipients are selected randomly from the targetIDs.
    49  	// TODO: function errors must be documented.
    50  	Multicast(event interface{}, num uint, targetIDs ...flow.Identifier) error
    51  
    52  	// Close unsubscribes from the channels of this conduit. After calling close,
    53  	// the conduit can no longer be used to send a message.
    54  	Close() error
    55  }
    56  
    57  // PeerUnreachableError is the error when submitting events to target fails due to the
    58  // target peer is unreachable
    59  type PeerUnreachableError struct {
    60  	Err error
    61  }
    62  
    63  // NewPeerUnreachableError creates a PeerUnreachableError instance with an error
    64  func NewPeerUnreachableError(err error) error {
    65  	return PeerUnreachableError{
    66  		Err: err,
    67  	}
    68  }
    69  
    70  // Unwrap returns the wrapped error value
    71  func (e PeerUnreachableError) Unwrap() error {
    72  	return e.Err
    73  }
    74  
    75  func (e PeerUnreachableError) Error() string {
    76  	return fmt.Sprintf("%v", e.Err)
    77  }
    78  
    79  // IsPeerUnreachableError returns whether the given error is PeerUnreachableError
    80  func IsPeerUnreachableError(e error) bool {
    81  	var err PeerUnreachableError
    82  	return errors.As(e, &err)
    83  }
    84  
    85  // AllPeerUnreachableError returns whether all errors are PeerUnreachableError
    86  func AllPeerUnreachableError(errs ...error) bool {
    87  	for _, err := range errs {
    88  		if !IsPeerUnreachableError(err) {
    89  			return false
    90  		}
    91  	}
    92  	return true
    93  }