Open emil14 opened 7 months ago
Hi, Does this issue imply something like 2x
is hard?
E.g.
2 -> x
x -> adder[0]
x -> adder[1]
addr[res] -> out
@ajzaff hey there
Not really, this is about more complex cases. Your example can be covered with single connection like this:
someNode:x -> [
adder:data[0],
adder:data[1]
]
adder:res -> :someOutport
In case x
is constant then it's $x -> ...
and rest is the same.
So here's real example, sub-component from 99 bottles example:
const {
firstLineTpl string = '$0 bottles of beer on the wall, $0 bottles of beer.'
secondLineTpl1 string = 'Take one down and pass it around, $0 bottles of beer on the wall.'
secondLine2 string = 'Take one down and pass it around, no more bottles of beer on the wall.'
}
component Looper(old int) (new int) {
nodes {
Eq<int>
Printer<any>
Decrementor<int>
fprinter1 FPrinter<int>
fprinter2 FPrinter<int>
}
net {
// print first line
:old -> [
fprinter1:args[0],
($firstLineTpl -> fprinter1:tpl)
]
// decrement from old
fprinter1:args[0] -> decrementor:data
// if decremented == 0
decrementor:res -> [
eq:a,
(0 -> eq:b)
]
// then print second line and end send new to out
eq:then -> ($secondLine2 -> printer:data)
printer:sig -> (eq:then -> :new)
// else print another second line
eq:else.a -> [
fprinter2:args[0],
($secondLineTpl1 -> fprinter2:tpl)
]
// and send new to out
fprinter2:args[0] -> :new
}
}
These lines:
eq:then -> ($secondLine2 -> printer:data)
printer:sig -> (eq:then -> :new)
Causes problem.
eq:then
sends a message (in this current example is 0
int)printer:sig
sends message (some string), we wanna use that signal to send message from eq:then
to :new
outport but the message from Eq is already sent and lost.This specific example can be solved by using explicitly 0
instead of reusing eq:then
but there are probably cases where this is impossible.
Possible solution would be iterating over all connections of a desugared program (it's important, desugarer inserts virtual connections) and grouping them by sender.
We can explicitly use Blocker
component instead of deferred connections
Because runtime implements sort-of pub-sub algorithm based on spawning a goroutine per connection where connection is one sender -> multiple receivers.
If we have e.g. 2 connections with the same
foo:bar
receiver, then we got 2 goroutines each receiving fromfoo:bar
. So we miss message in one of these two goroutines.We have 2 ways to fix this, easy and hard (I like the easy one, it's good for language API)
Might be related to https://github.com/nevalang/neva/issues/627