trustmaster / goflow

Flow-based and dataflow programming library for Go (golang)
MIT License
1.6k stars 125 forks source link

Feature request: Broadcast from one proc port to n proc ports #38

Closed phiros closed 3 months ago

phiros commented 7 years ago

It would be really helpful to have a specialized Connect function which connects the output port of one component to n input ports. Something like:

func (n *Graph) ConnectBroadcast(senderName, senderPort, clientPorts ...[]string) bool

where clientPorts are tuples of proc names & ports

As far as I can see there is no easy way to have a broadcast component in goflow without such a function.

abferm commented 6 years ago

I'd love to have this too, although it would probably be better to do something like this.

type Address struct{
    Process, Port string
}
func (n *Graph) ConnectBroadcast(sender Address, receivers ...Address) bool
trustmaster commented 4 years ago

In v1 you can call .Connect() multiple times with the same sender, e.g.:

net.Connect("src", "Out", "d1", "In")
net.Connect("src", "Out", "d2", "In")

However, in this case src will not broadcast the IP to all of its receivers, but rather let the first of them which is ready to consume the packet.

The original FBP book disallows connecting a single sender port to multiple receiver port, because the semantics of such a connection is not clear: should the sender replicate the package or send the same one, which load-balancing algorithm should be used? Instead, it says, fan-out or broadcasting should be implemented with explicit components which make the semantics clear when looking at the graph. An example of such component would look like

// Broadcaster copies an incoming message to all components connected to its array Out port
type Broadcaster struct {
    In <-chan Message
    Out []chan<- Message // array port, allows for arbitrary connections
}
dahvid commented 3 years ago

There are certain features I would like to have that perhaps would be better added through specialty built-in nodes. This is one of them. In a situation like this in a single memory space it's not clear if a broadcast means broadcasting a pointer to the same memory location, or copying the object sent. Inserting a standard BroadCast Component to the channel desiring broadcast would make this explicit. Another area is AND semantics on input ports, that is, Process() is only called when data exists in all input ports. Examples has a way to code this yourself, but a standard component could provide this feature and then be inherited.