Replies: 5 comments 3 replies
-
This seems reasonable. The statement "the reaction can simply be set aside in a set of pending reactions" may be a little is misleading, however, because we have be careful to not confuse "set aside" with completion of the reaction. So it may not be quite so simple. The system has to behave as if the reaction takes a long time to execute, so that any dependent reactions are also blocked. |
Beta Was this translation helpful? Give feedback.
-
Yes, depending reactions will also be blocked. Causal influence of network ports is transitive, so any reaction that is causally influenced by a reaction that is side aside will itself also be be set aside. By "set aside" I just mean stored in a "pending set," to be pushed onto the reaction queue whenever all upstream network ports have their status known. |
Beta Was this translation helpful? Give feedback.
-
It appears like the overarching problem with this solution has to do with determining whether we have something ready on a port before we can propagate a port status to downstream dependencies. As it stands, we accomplish this using busy waiting on reading from a port using sockets. I have a possible solution to this that doesn't require additional threads to block, but requires more centralized control of the entire socket. Rather than reading synchronously from a socket, we can set a connection to be async using fcntl. (Note: The below explanation also works on Ubuntu using Epoll with similar implementations) The way this may work is to start the federate by setting up a KQueue and KEvents for the federates socket to listen on both input (and possibly output) ports. We will start by running any events that are not blocked by port statuses. Once we exhaust the queue, we can read off of the KQueue to see if we have any network messages to process. Once processed, depending on whether its a read or write, you process said event. If its an input port indicating its status (absent or present w/ a value), we can set a global value for the port being ready and go through a waiting reaction queue to see if all its global value for input ports are set before enqueuing said reaction onto the reaction queue. Depending on what test cases fail, we would need to tweak when to poll the KQueue. Per my discussion with Edward, this seems like a middle ground solution between busy waiting and polling each individual port separately. Rather than polling all ports, this simply populates a queue that automatically loads with events to be processed (seems like the read syscall simply waits for the queue to populate with an event corresponding to what its reading before unblocking). We would need to find an optimal time to read (and whether we can preempt the current thread via a signaled interrupt when there is something on the kernel queue) This will need some work to put together, but it seems like it's worth looking into. |
Beta Was this translation helpful? Give feedback.
-
To be clear, the current solution does not busy wait. It sets up a thread that blocks on socket activity. |
Beta Was this translation helpful? Give feedback.
-
This seems like basically the same idea as chain ID. If both are implemented, the two might use much of the same code. |
Beta Was this translation helpful? Give feedback.
-
The current federated architecture (also see #608) employs blocking unordered reactions dubbed "input control reactions" to allow for cyclic connection topologies in federations. While this approach clearly works, it requires the use of many dedicated threads, most of which are simply waiting or inactive most of the time. There are concerns about scalability of the approach, as well as a perceived difficulty to understand the current state of a federate, which is mainly a concern for when debugging. @arengarajan99 and I have been discussing ways of doing this differently. Here are some observations made during our conversation:
Beta Was this translation helpful? Give feedback.
All reactions