Closed emil14 closed 1 year ago
This one only fixes number 4 problem
There already was an idea of using ctx
as a extendable part of the runtime functions so why don't we just use it to pass a message, or a map of messages, or any other container (if container needed (we probably want less givers than more givers))
Spawning goroutines that sends messages is obviously cheaper than spawning goroutines that reads values from ctx
and only then sends them. On the other hand - this only happens at startup. Is performance penalty big enough so we don't wanna get rid of everything except runtime functions?
Who's gonna pass msg to ctx? There's only one place - func runner. That means there should be some logic like "spawn functions but sometimes insert msg into ctx". That "sometimes" must be implemented somehow like this
runtimeFunc {
msg Msg // only make sense for giver component
...
}
That's obviously bad design and current solution with routines
and giverRoutine
is better
staticPorts
to network
. Option 1. Duality port | msg
and almost no changesJust remove staticPorts
from nodes
and try to reuse existing structure as-is without changing anything. There will be some if
in the code like "if it points to a message, not component, then it's a static-port".
Let's take a look at current structure:
type Connection struct {
SenderSide ConnectionSide
ReceiverSides []ConnectionSide
}
type ConnectionSide struct {
PortAddr ConnPortAddr
Selectors []Selector
}
type ConnPortAddr struct {
Node string // and this probably should be package
RelPortAddr
}
type RelPortAddr struct {
Name string // this probably should be a message name
Idx uint8 // this have no use for static message (not even for arrays, at least because we want selectors)
}
So at the end of the day we end up with something like
type ConnectionSideRef struct {
NodeOrPkg string
LocalRef
}
type LocalRef struct {
PortNameOrPkg string
Idx uint8 // not used for messages
}
It's possible to end up with better naming but it's obvious to me that this is a bad design
type Connection struct {
SenderSide SenderConnectionSide
ReceiverSides []ReceiverConnectionSide
}
type SenderConnectionSide struct {
PortAddr ConnPortAddr
Selectors []Selector
}
type Selector struct {
RecField string // "" means use ArrIdx
ArrIdx int
}
type ConnPortAddr struct {
Node string
RelPortAddr
}
type RelPortAddr struct {
Name string
Idx uint8
}
type ReceiverConnectionSide struct { // === New code ===
Msg *Msg // non nil msg means static port
PortAddr ConnPortAddr
Selectors []Selector
}
Interpretation part of this data can make obvious decisions like "if there's a message then add IR giver and connect it ti that port"
Closed due to choosing https://github.com/nevalang/nevalang/issues/256#issuecomment-1489020579
This issue describes 4 problems with current design of static messages
selectors
with static messages right nownodes
leads to a special case (there's no incoming connections to inports bound to messages)nodes
structure (node
andinstance
types instead of just node)There's special
giver
routine and because of that we have to have not justruntime functions
but the more abstractroutines
of 2 kindsThat complexity will go otherwise from nodes to network because we gonna introduce some second type (or is there another way?) of a incoming connection. It's like there will be "normal connection to an outport" and "connection to a message"
On the other hand there's a way to introduce more types of routines that way (not sure actually that's a good idea)
in order to use
selectors
we have to eitherstaticPorts
config object withselectors
(which will mixnodes
withnetwork
) ORnetwork
where we haveselectors
alreadyMoving to network will also fix 2 and 3 problems
There's only one way to fix this - get rid of
routines
andgivers
as a concept and create aruntime function
that could serve the same purpose - send predefined messages across specified inports throughout the network.(For historical purposes - the "giver" issue was discussed in #161 and #106).