github.com/koko1123/flow-go-1@v0.29.6/network/p2p/conduit/conduit.go (about) 1 package conduit 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/koko1123/flow-go-1/model/flow" 8 "github.com/koko1123/flow-go-1/network" 9 "github.com/koko1123/flow-go-1/network/channels" 10 ) 11 12 // DefaultConduitFactory is a wrapper around the network Adapter. 13 // It directly passes the incoming messages to the corresponding methods of the 14 // network Adapter. 15 type DefaultConduitFactory struct { 16 adapter network.Adapter 17 } 18 19 func NewDefaultConduitFactory() *DefaultConduitFactory { 20 return &DefaultConduitFactory{} 21 } 22 23 // RegisterAdapter sets the Adapter component of the factory. 24 // The Adapter is a wrapper around the Network layer that only exposes the set of methods 25 // that are needed by a conduit. 26 func (d *DefaultConduitFactory) RegisterAdapter(adapter network.Adapter) error { 27 if d.adapter != nil { 28 return fmt.Errorf("could not register a new network adapter, one already exists") 29 } 30 31 d.adapter = adapter 32 33 return nil 34 } 35 36 // NewConduit creates a conduit on the specified channel. 37 // Prior to creating any conduit, the factory requires an Adapter to be registered with it. 38 func (d *DefaultConduitFactory) NewConduit(ctx context.Context, channel channels.Channel) (network.Conduit, error) { 39 if d.adapter == nil { 40 return nil, fmt.Errorf("could not create a new conduit, missing a registered network adapter") 41 } 42 43 child, cancel := context.WithCancel(ctx) 44 45 return &Conduit{ 46 ctx: child, 47 cancel: cancel, 48 channel: channel, 49 adapter: d.adapter, 50 }, nil 51 } 52 53 // Conduit is a helper of the overlay layer which functions as an accessor for 54 // sending messages within a single engine process. It sends all messages to 55 // what can be considered a bus reserved for that specific engine. 56 type Conduit struct { 57 ctx context.Context 58 cancel context.CancelFunc 59 channel channels.Channel 60 adapter network.Adapter 61 } 62 63 // Publish sends an event to the network layer for unreliable delivery 64 // to subscribers of the given event on the network layer. It uses a 65 // publish-subscribe layer and can thus not guarantee that the specified 66 // recipients received the event. 67 func (c *Conduit) Publish(event interface{}, targetIDs ...flow.Identifier) error { 68 if c.ctx.Err() != nil { 69 return fmt.Errorf("conduit for channel %s closed", c.channel) 70 } 71 return c.adapter.PublishOnChannel(c.channel, event, targetIDs...) 72 } 73 74 // Unicast sends an event in a reliable way to the given recipient. 75 // It uses 1-1 direct messaging over the underlying network to deliver the event. 76 // It returns an error if the unicast fails. 77 func (c *Conduit) Unicast(event interface{}, targetID flow.Identifier) error { 78 if c.ctx.Err() != nil { 79 return fmt.Errorf("conduit for channel %s closed", c.channel) 80 } 81 return c.adapter.UnicastOnChannel(c.channel, event, targetID) 82 } 83 84 // Multicast unreliably sends the specified event to the specified number of recipients selected from the specified subset. 85 // The recipients are selected randomly from targetIDs 86 func (c *Conduit) Multicast(event interface{}, num uint, targetIDs ...flow.Identifier) error { 87 if c.ctx.Err() != nil { 88 return fmt.Errorf("conduit for channel %s closed", c.channel) 89 } 90 return c.adapter.MulticastOnChannel(c.channel, event, num, targetIDs...) 91 } 92 93 func (c *Conduit) Close() error { 94 if c.ctx.Err() != nil { 95 return fmt.Errorf("conduit for channel %s already closed", c.channel) 96 } 97 // close the conduit context 98 c.cancel() 99 // call the close function 100 return c.adapter.UnRegisterChannel(c.channel) 101 }